eww icon indicating copy to clipboard operation
eww copied to clipboard

[BUG] eww slowly fills ram

Open FinleyBuhl opened this issue 1 year ago • 11 comments

Checklist before submitting an issue

  • [X] I have searched through the existing closed and open issues for eww and made sure this is not a duplicate
  • [X] I have specifically verified that this bug is not a common user error
  • [X] I am providing as much relevant information as I am able to in this bug report (Minimal config to reproduce the issue for example, if applicable)

Description of the bug

When I let eww run for a while I notice that it's slowly filling the ram. The speed it's filling the ram with seems to be dependent on how often defpolls are executed. This isn't caused by variables getting bigger, as they don't really change in terms of size.

Reproducing the issue

Just create a lot of defpolls with very short intervals

Expected behaviour

No response

Additional context

` (defvar app_menu_reveal "false") (defvar power_menu_reveal "false") (defvar show_apps "false")

(defvar reveal_app_terminal "false") (defvar reveal_app_vscode "false")

(defvar ram_dropdown_reveal "false") (defvar disk_dropdown_reveal "false") (defvar cpu_dropdown_reveal "false")

(defpoll time :interval "0.5s" :initial "" 'date "+%T"' )

(defpoll cpu :interval "0.5s" '/home/finley/.config/eww/cpu.sh' )

(defpoll root_percent :interval "1s" :initial "" '/home/finley/.config/eww/disk-percent.sh' )

(defpoll disks :interval "1s" '/home/finley/.config/eww/disks.sh' )

(defpoll proc :interval "0.5s" '/home/finley/.config/eww/proc.sh' )

(defpoll hypr :interval "0.5s" '/home/finley/.config/eww/hypr.sh' )

(defpoll apps :interval "1000s" 'cat /home/finley/.config/eww/apps.json' )

(defpoll volume :interval "0.1s" pactl list sinks | grep 'Volume: front-left' | awk '{print $5}' | sed 's/%//' | head -n 1 )

(include "/home/finley/.config/eww/variables.yuck")

(defwidget volume [] (box :class "volume_box" :space-evenly false :spacing 5; (scale :class "volume" :orientation "h" :width "200" :min 0 :max 100 :value "${volume}" :draw-value false :onchange "/home/finley/.config/eww/volume-change.sh {}" ) (box :class "volume_buttons" (eventbox :onclick (label :class "volume_buttons_label" :text "+" ) ) (eventbox :onclick (label :class "volume_buttons_label" :text "-" ) ) ) ) )

(defwidget pie_chart [val icon name] (box :spacing 0 :class "${name}" (circular-progress :start-at "75" :clockwise true :thickness 15 :value "${val}" ) (label :text "${icon} " ) ) )

(defwidget cpu [] (eventbox :onhover "${EWW_CMD} update cpu_dropdown_reveal=true" :onhoverlost "${EWW_CMD} update cpu_dropdown_reveal=false" (pie_chart :val "${cpu}" :icon "" :name "cpu" ) ) )

(defwidget ram [] (eventbox :onhover "${EWW_CMD} update ram_dropdown_reveal=true" :onhoverlost "${EWW_CMD} update ram_dropdown_reveal=false" (pie_chart :val "${EWW_RAM.used_mem_perc}" :icon "" :name "ram" ) ) )

(defwidget disk [] (eventbox :onhover "${EWW_CMD} update disk_dropdown_reveal=true" :onhoverlost "${EWW_CMD} update disk_dropdown_reveal=false" (pie_chart :val "${round(root_percent, 1)}" :icon "" :name "disk" ) ) )

(defwidget app_menu_item [icon command class] (eventbox :onclick "${command}" (label :class "${class}" :text "${icon}" ) ) )

(defwidget app_menu_v2 [apps] (eventbox :onhover "${EWW_CMD} update show_apps=true" :onhoverlost "${EWW_CMD} update show_apps=false" (box :class "app_menu" :space-evenly false (image :path "${EWW_CONFIG_DIR}/apps.png" ) (revealer :reveal "${show_apps}" :transition "slideleft" :duration "0.1s" (box :spacing 0 :hexpand false (for item in apps (eventbox :onclick "bash -c '${item.command} & disown $(jobs -lp)'" (image :path "${item.icon}" :class "app_menu_item" ) ) ) ) ) ) ) )

(defwidget power_menu [] (eventbox :onhover "${EWW_CMD} update power_menu_reveal=true" :onhoverlost "${EWW_CMD} update power_menu_reveal=false" (box :class "power_menu" :spacing 10 :space-evenly false (revealer :transition "slideleft" :reveal "${power_menu_reveal}" :duration "200ms" (box :spacing 15 :space-evenly false (label) (app_menu_item :icon "" :command "reboot" :class "power_menu_reboot" ) ) ) (app_menu_item :icon "" :command "shutdown" :class "power_menu_shutdown" ) ) ) )

(defwidget clock [] (box :class "clock_box" (label :class "clock" :text "${time}" ) ) )

(defwidget cpu_dropdown [] (revealer :reveal "${cpu_dropdown_reveal}" :transition "slideleft" :visible "${cpu_dropdown_reveal}" (box :class "cpu_dropdown" :orientation "vertical" :spacing 5 ;(for obj in proc ; (box ; :class "cpu_dropdown_entry" ; (label ; :halign "start" ; :class "cpu_dropdown_name" ; :text "${obj.command}" ; ) ; (label ; :halign "end" ; :class "cpu_dropdown_usage" ; :text "${obj.cpu_percent}" ; ) ; ) ;) ) ) )

(defwidget ram_dropdown [] (revealer :reveal "${ram_dropdown_reveal}" :transition "slideleft" :visible "${ram_dropdown_reveal}" (box :spacing 0 :class "ram_dropdown" :orientation "vertical" (label :halign "start" :text "total: ${round(EWW_RAM.total_mem / 1024 / 1024 /1024, 1)}gb" :class "ram_dropdown_text" ) (label :halign "start" :text "used: ${round(EWW_RAM.used_mem / 1024 / 1024 /1024, 1)}gb" :class "ram_dropdown_text" ) (label :halign "start" :text "free: ${round(EWW_RAM.free_mem / 1024 / 1024 /1024, 1)}gb" :class "ram_dropdown_text" ) ) ) )

(defwidget disk_dropdown [] (revealer :reveal "${disk_dropdown_reveal}" :transition "slideleft" :visible "${disk_dropdown_reveal}" (box :space-evenly false :spacing 5 :class "disk_dropdown" :orientation "vertical" :vexpand "false" (for obj in disks (box :space-evenly false :vexpand "false" :orientation "vertical" :spacing 2 (label :class "disk_dropdown_name" :halign "start" :text "${obj.mount}" ) (progress :class "disk_dropdown_progress" :orientation "horizontal" :value "${obj.used_perc}" :vexpand true :hexpand true ) (box :spacing 0 :orientation "vertical" :class "disk_dropdown_values" (box (label :class "disk_dropdown_text" :halign "start" :text "total:" ) (label :class "disk_dropdown_text" :halign "end" :text "${obj.total}" ) ) (box (label :class "disk_dropdown_text" :halign "start" :text "used:" ) (label :class "disk_dropdown_text" :halign "end" :text "${obj.used}" ) ) (box (label :class "disk_dropdown_text" :halign "start" :text "free:" ) (label :class "disk_dropdown_text" :halign "end" :text "${obj.free}" ) ) ) ) ) ) ) )

(defwidget workspaces [] (box :class "workspaces" :spacing 3 (for obj in hypr (eventbox :onclick "hyprctl dispatch workspace ${obj.id} > ~/test" (label :class "workspaces_item" :text "${obj.windows}" ) ) ) ) )

(include "/home/finley/.config/eww/widgets.yuck")

(defwindow bar :class "bar_left" :monitor 1 :geometry (geometry :x "0px" :y "10px" :width "3830px" :height "30px" :anchor "top center" ) :stacking "fg" :exclusive true :windowtype "dock" (box :space-evenly true (box :spacing 10 :space-evenly false (box :space-evenly false (cpu) (ram) (disk) (workspaces) )

        (box
            :space-evenly false
            (volume)
            (app_menu_v2 :apps "${apps}")
        )
    )
    (box
        :halign "center"
        (clock)
    )
    (box
        :width "0"
        :halign "end"
        :space-evenly false
        (power_menu)
    )
)

)

(defwindow cpu_dropdown :class "cpu_dropdown" :monitor 1 :geometry (geometry :x "5px" :y "0px" :width "0" :height "0px" :anchor "top left" ) :windowtype "normal" :stacking "fg" (box (cpu_dropdown) ) )

(defwindow ram_dropdown :class "ram_dropdown" :monitor 1 :geometry (geometry :x "65px" :y "0px" :width "0" :height "0px" :anchor "top left" ) :windowtype "normal" :stacking "fg" (box (ram_dropdown) ) )

(defwindow disk_dropdown :class "disk_dropdown" :monitor 1 :geometry (geometry :x "127px" :y "0px" :width "0" :height "0px" :anchor "top left" ) :windowtype "normal" :stacking "fg" (box (disk_dropdown) ) ) `

FinleyBuhl avatar Jun 07 '23 14:06 FinleyBuhl

My guess is that this issue isn't related to the defpolls themselves, but to the use of the for widget, which is sadly known to have a few issues (that I should really get into).

elkowar avatar Jun 09 '23 14:06 elkowar

Thanks for responding so quickly! I guess I'll just try to outsource it to a script and use a literal for now.

FinleyBuhl avatar Jun 10 '23 00:06 FinleyBuhl

Can confirm the issue and that it's not related to defpoll. Eww daemon starts at 49 megs for me and grows to 400 (and over) megs over the time with unusable latency for the redrawing of for on deflisten value (current workspace) at the end of it. It happens with the example workspaces widget from the Hyprland wiki: https://wiki.hyprland.org/Useful-Utilities/Status-Bars/#eww and you can actually see the memory grow/leak by rapidly switching workspaces back and worth. Started using Eww only recently, but was that issue there all the time? How one can work around it? Eww seem to allow for some awesome stuff, but this for issue is a big hurdle for using it

nativerv avatar Jun 13 '23 13:06 nativerv

Same observation here. At some point I even observed eww using 1.4GB of RAM. As I'm writing this, my eww is jumping around 26 MB, 500 MB, and even 1 GB at some point in a matter of 2 seconds. One second, it's 26 MB, next second, it's 500 MB, 800 MB, and back to ~200 MB. Additionally, eww is using 7% of my CPU (i7-11700H) and forced my RAM to swap, putting a further burden on the CPU.

image image image image

Workspaces script and eww configuration

SIMULATAN avatar Jun 19 '23 12:06 SIMULATAN

Alrighty, little update. Or, well, quite a substantial one.

Eww ended up growing even more, and suddenly (while working), I found out that my file system was full. So I checked the usage and found a 130 GB log file by eww. I then deleted that file, but surprise surprise, while du and ncdu showed that the file was gone and i had like 125 GB of free space, df showed the disk as 100% full with 64 KB of space left. After some further debugging in random directions as I didn't see the correlation to eww, I ended up closing the bar just to be safe, and killed eww. However, that first didn't work, in fact, it made the process <defunct>. After another attempt, it ended up killing it, and indeed, I just regained 125 GB of disk space. In the time that the disk was full, my firefox profile data corrupted, leading to all my cookies being deleted, and me having to re-login to every. single. website I use.

before killing eww while killing eww i don't have a screenshot of deleting the log file as I expected that to just fix it

The log file was filled with "Widget was deallocated" errors by the way.

SIMULATAN avatar Jun 21 '23 09:06 SIMULATAN

@SIMULATAN the eww log file growing is a known issue (#750). There is a hacky """fix""" (just removing the log) but we'd need a proper one to be merged. However since this bug is very problematic it might be smarter to just merge a bad workaround for the time being to avoid causing too many problems (@elkowar ?)

viandoxdev avatar Jun 22 '23 09:06 viandoxdev

Hi, just like @SIMULATAN i am facing a workspace widget issue in hyprland (the workspaces.yuck file has for widget in it). Any updates on this issue?

estnml avatar Sep 18 '23 21:09 estnml

how is this issue going? its getting really slow using hyprland.

Y0ngg4n avatar Dec 03 '23 21:12 Y0ngg4n

I refactored my eww recently to use the for function to display my hyprland workspaces, and I started noticing a slowdown as well. It's not limited to the increase in ram usage, though I was able to track the leak. It was also increasingly spiking the cpu usage when it would update leading to screen tearing when switching workspaces. This didn't improve by simply reloading eww. The screen tearing only goes away when the eww daemon is closed.

TroubleClef128 avatar Dec 18 '23 18:12 TroubleClef128

I have noticed this issue recently with the for loop. I am using it to iterate over a json array that contains workspaces and the icons of windows within them. My ram would slowly build up and would be accelerated if I increase the polling rate of the varpoll that the for element uses.

Eww would only slowly increase in memory after about 5 minutes of it running without reloading the config. And will remain high untill you restart the daemon.

The way I fixed it is in my bash scripts I format the output in raw yuck and passed that into the variable. I use a literal element to then parse the yuck and have it displayed.

I have been running this for a while and eww has remained at 64Mb of memory usage from the previous 8Gb. I can count this as a fix for me. Ill post another update if I notice anything more.

JonathanSteininger avatar Jan 08 '24 22:01 JonathanSteininger

I think this can be closed in regard to https://github.com/elkowar/eww/pull/1010

0xk1f0 avatar Feb 17 '24 17:02 0xk1f0