windows-terminal-quake icon indicating copy to clipboard operation
windows-terminal-quake copied to clipboard

[Linux] Very high memory usage

Open nabaxo opened this issue 1 month ago β€’ 27 comments

I'm not sure if it's been reported before, but WTQ running in Linux (Fedora KDE 43 and before) uses up like 700MB-1GB of RAM.

Image

nabaxo avatar Nov 14 '25 09:11 nabaxo

@nabaxo Thank you for reporting this!

Could you share your settings file?

Also, what installation method are you using?

flyingpie avatar Nov 14 '25 19:11 flyingpie

Here's my settings:

{
	"$schema": "wtq.schema.json",
	"Apps": [
		{
			"Name": "Wezterm",
			"Hotkeys": [
				{
					"Modifiers": "Super",
					"KeyChar": "`"
				},
				{
					"Modifiers": "Super",
					"KeyChar": "Β§"
				}
			],
			"FileName": "wezterm-gui",
			"Arguments": "start --class=wezquake",
			"ProcessName": "wezquake"
		}
	],
	"AnimationTargetFps": 120,
	"HideOnFocusLost": "Never",
	"HorizontalScreenCoverage": 40,
	"VerticalScreenCoverage": 40,
	"AnimationDurationMs": 350,
	"AnimationTypeToggleOn": "EaseOutCubic",
	"AnimationTypeToggleOff": "EaseInQuart"
}

I installed with the script I think.

nabaxo avatar Nov 14 '25 22:11 nabaxo

At the moment it's "only" using 300mb though. But that's still quite a lot.

nabaxo avatar Nov 14 '25 22:11 nabaxo

Way too much, totally agree.

Seems to be some weird stuff going on somewhere, need to try and find out where all this unmanaged memory is coming from:

Image

flyingpie avatar Nov 15 '25 00:11 flyingpie

Some observations so far:

  • (Part of it) may be Linux-specific, use quickly grows to 300-400MB+, whereas on Windows generally usage hovers around 60-100MB. Found these issues that may or may not be relevant [1]
  • The native dependencies (such as webkit for the GUI) seem to have some part in it, as a big chunk of the unmanaged memory is allocated right from the start (like ~300-400MB), which doesn't happen when disabling these components
  • There are definitely areas in the code that can use some optimization or reconsideration, like not having the gui running all the time, and the log window
  • There seems to also be some longer-term component going on, where after the initial 400MB chunk, memory can grow to over a gig. Not sure if that's coming from the managed or unmanaged part.

[1]

  • https://github.com/dotnet/runtime/issues/95922
  • https://github.com/dotnet/runtime/issues/96091

@nabaxo Are you in a position where you could make memory dumps, e.g. with dotnet-dump?

flyingpie avatar Nov 16 '25 19:11 flyingpie

With instructions, I could provide the memory dumps.

nabaxo avatar Nov 17 '25 09:11 nabaxo

I'd like to scope this issue to the scenario where memory balloons from ~300MB to 700-1000. It seems (for me at least) that generally, the memory usage on Linux is hovering around 300MB, but in some cases can blow up to about 1GB.

I do think that 300MB is still a bit much, but current observations suggest that that can be a stable operating usage, whereas increases to 1GB are more exceptional.

If you're up for it, you could make a dump (teehee) when this happens, with these steps:

  • Have .Net 9 installed
  • Install the "dotnet-dump" tool: dotnet tool install --global dotnet-dump
  • When memory is particularly high, dump wtq's core: dotnet-dump collect -n wtq

flyingpie avatar Nov 18 '25 23:11 flyingpie

The .NET 9, is that the dotnet-sdk? I'm just looking to install it easily on my distro.

nabaxo avatar Nov 20 '25 08:11 nabaxo

The .NET 9, is that the dotnet-sdk? I'm just looking to install it easily on my distro.

Yes!

flyingpie avatar Nov 20 '25 10:11 flyingpie

Uh, running dotnet-dump collect -n wtq dumped a 70GB file on my disk.

nabaxo avatar Nov 20 '25 11:11 nabaxo

How do you want the dump then? It's still there.

nabaxo avatar Nov 21 '25 07:11 nabaxo

How do you want the dump then? It's still there.

I'll get back to you, also got a massive memory dump myself, kinda weird.

flyingpie avatar Nov 21 '25 18:11 flyingpie

One way to get a high-level view of what's going on, is by dumping the virtual memory mapping:

pmap -x $(ps -C wtq -o pid=) > vmem.txt

The "ps" part pulls out the wtq process id, which is then fed into "pmap", which dumps a list of memory regions.

If you could paste that here, or as an attachment, we could get a first look at where the memory is going.

On my machine, what I'm seeing is a bunch of memory coming from native libraries, that are usually not mapped into physical memory, but when they do, increase usage to the earlier seen 700-800MB.

Much of these seem to relate to the GUI, so I'd like to track memory usage on a headless build of wtq, see if where it maxes out on.

Here are some of the larger modules loaded in, with some parts swapped out: Image

Here is the total of all modules, full size (~700MB):

Image

Here's the resident parts, i.e. the actually loaded in parts ~137MB:

Image

Both screenshots have excluded the runtime memory allocated by the CLR, which show up as "[ anon ]".

So my hypothesis is that the difference we're seeing is mostly in native libraries, not necessarily incredibly inefficient use by the app itself, or memory leaks.

Hopefully a headless build could shed some light on that.

flyingpie avatar Nov 22 '25 16:11 flyingpie

@nabaxo Assuming most of the memory usage does indeed come from the GUI-related libraries, can you tell me your use of the GUI? I.e., what are your thoughts on making the GUI a setting, or maybe even a separate executable or something?

Additionally, I've added a prerelease that disables the GUI entirely (aside from the tray icon, if you count that as "GUI").

Are you willing to test drive that for a bit, see what happens to the memory usage?

The release also switches to "Invariant Mode", which removes another ~20MB-30MB from the heap.

Image

flyingpie avatar Nov 22 '25 22:11 flyingpie

As for your first question, here's the dump. vmem.txt

As for the second, I personally just use the JSON, but the GUI is a useful option. It is absolutely necessary for most regular users though. Maybe make the GUI standalone.

Anyway, taking the pre-release for a spin and see how that works out!

nabaxo avatar Nov 23 '25 12:11 nabaxo

Quick update, it still uses ~500mb.

Here's the new vmem-dump:

vmem2.txt

nabaxo avatar Nov 23 '25 12:11 nabaxo

Quick update, it still uses ~500mb.

Here's the new vmem-dump:

vmem2.txt

Thank you for taking the effort!

I'm confused at the result though, as this seems to indicate ~150MB:

Image

How are you determining the memory, i.e. what is saying 500MB?

flyingpie avatar Nov 23 '25 15:11 flyingpie

Here's what system monitor is saying:

Image

And here's what Mission Center is saying:

Image

nabaxo avatar Nov 24 '25 08:11 nabaxo

What the hell πŸ˜„

What does this show?

ps -u -p $(ps -C wtq -o pid=)

Running this prerelease hasn't cracked 70MB on my machine, the plot thickens!

USER         PID  %CPU %MEM    VSZ       RSS   TTY   STAT START   TIME  COMMAND
marco     389188  0.9  0.0     276392352 63868 ?     Ssl  Nov23   26:59 /home/marco/.local/share/wtq/wtq
                                         ^^^^^ ~64MB

flyingpie avatar Nov 24 '25 23:11 flyingpie

Here you go!

USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
nabaxo      2903  0.3  0.2 276515128 147820 ?    Ssl  Nov24   4:05 /home/nabaxo/.local/share/wtq/wtq

nabaxo avatar Nov 25 '25 07:11 nabaxo

Okay, I'm still reading up on how to actually interpret all these numbers, but couple points meanwhile.

Recognizing that memory usage is not as simple as it may sound, one thing kinda wild is how much different applications can differ in their memory reporting.

Here's a VM with Fedora 43 KDE, with KDE System Monitor and Mission Center:

Image

That's running the Flatpak version of Mission Center, is that the one you also use, or are you using it through Copr or something? It's the stable release of WTQ, with full GUI. So this does come quite close to the numbers you're seeing, at least on the Mission Center side.

Could you show the output of this:

cat /proc/$(pidof -s wtq)/smaps_rollup

Also, not to be that guy, but are you sure the last numbers are from the headless pre-release?

As a test, the version should say "2.0.19", and clicking "Open Main Window" should do nothing.

Image

flyingpie avatar Nov 25 '25 23:11 flyingpie

Here's the output:

╰─ cat /proc/$(pidof -s wtq)/smaps_rollup
55a75a36c000-7fffbb039000 ---p 00000000 00:00 0                          [rollup]
Rss:              150460 kB
Pss:              121695 kB
Pss_Dirty:         69384 kB
Pss_Anon:          43764 kB
Pss_File:          52243 kB
Pss_Shmem:         25688 kB
Shared_Clean:      36416 kB
Shared_Dirty:         24 kB
Private_Clean:     44648 kB
Private_Dirty:     69372 kB
Referenced:       150460 kB
Anonymous:         43764 kB
KSM:                   0 kB
LazyFree:              0 kB
AnonHugePages:         0 kB
ShmemPmdMapped:        0 kB
FilePmdMapped:         0 kB
Shared_Hugetlb:        0 kB
Private_Hugetlb:       0 kB
Swap:                  0 kB
SwapPss:               0 kB
Locked:                0 kB

I am indeed running the version:

Image

Then when it comes to mission center, I am running the flatpak version. But ever since an update on dotnet-9, this is what mission center reports: Image

And this is what System Monitor reports: Image

nabaxo avatar Nov 26 '25 08:11 nabaxo

More questions πŸ™‚

Are you running the framework-dependent, or the self-contained version?

Also, I'm seeing weird stuff, here's the alleged usage from the overview screen in KDE System Monitor:

Image

And here's the one in the process detail tab:

Image

The smaps rollup tells me this:

558459dbe000-7ffed9f23000 ---p 00000000 00:00 0                          [rollup]
Rss:              148128 kB
Pss:              114818 kB
Pss_Dirty:         67256 kB
Pss_Anon:          46056 kB
Pss_File:          47457 kB
Pss_Shmem:         21304 kB
Shared_Clean:      41372 kB
Shared_Dirty:         28 kB
Private_Clean:     39484 kB
Private_Dirty:     67244 kB
Referenced:       122876 kB
Anonymous:         46056 kB
KSM:                   0 kB
LazyFree:              0 kB
AnonHugePages:     28672 kB
ShmemPmdMapped:        0 kB
FilePmdMapped:     12288 kB
Shared_Hugetlb:        0 kB
Private_Hugetlb:       0 kB
Swap:              18556 kB
SwapPss:           10088 kB
Locked:                0 kB

A factor that I didn't consider before, depending on the particular metric, any child processes could be taken into account when calculating the memory usage.

Since apps can be started from WTQ, this means that a system monitor app sees WTQ as its parent process, and may take the child process into account as part of WTQ's memory.

Here's a breakdown of my current process tree (all RSS):

wtq(3089)                          146MB
  -dolphin(3275)                   222MB
  -keepassxc(3322)                 210MB
  -plasma-systemmo(3300)           360MB
  -vesktop(1352300)               1500MB
  -wezterm-gui(3159)               480MB
----------------------------------------------
                                 ~2900MB

The combined usage approaches the KDE System Monitor overview's reported usage:

Image

So could you take a look at the process tree, starting at WTQ's process:

pstree -p $(pidof wtq)

You can also use something like htop for that, or do it straight from System Monitor even:

Image

This may solve part of the problem, i.e., tell us that we can trust the ~150MB figure that seems to come back from multiple apps.

flyingpie avatar Dec 01 '25 19:12 flyingpie

I'm using the self-contained version, here's the output of pstree -p $(pidof wtq):

wtq(2772)─┬─wezterm-gui(3100)─┬─zsh(3169)───pstree(23015)
          β”‚                   β”œβ”€{wezterm-gui}(3112)
          β”‚                   β”œβ”€{wezterm-gui}(3133)
          β”‚                   β”œβ”€{wezterm-gui}(3145)
          β”‚                   β”œβ”€{wezterm-gui}(3146)
          β”‚                   β”œβ”€{wezterm-gui}(3147)
          β”‚                   β”œβ”€{wezterm-gui}(3160)
          β”‚                   β”œβ”€{wezterm-gui}(3170)
          β”‚                   β”œβ”€{wezterm-gui}(3171)
          β”‚                   β”œβ”€{wezterm-gui}(3172)
          β”‚                   β”œβ”€{wezterm-gui}(3173)
          β”‚                   β”œβ”€{wezterm-gui}(3210)
          β”‚                   β”œβ”€{wezterm-gui}(3320)
          β”‚                   β”œβ”€{wezterm-gui}(3321)
          β”‚                   β”œβ”€{wezterm-gui}(3328)
          β”‚                   β”œβ”€{wezterm-gui}(3329)
          β”‚                   β”œβ”€{wezterm-gui}(3340)
          β”‚                   β”œβ”€{wezterm-gui}(3396)
          β”‚                   └─{wezterm-gui}(3413)
          β”œβ”€{wtq}(2816)
          β”œβ”€{wtq}(2817)
          β”œβ”€{wtq}(2819)
          β”œβ”€{wtq}(2820)
          β”œβ”€{wtq}(2822)
          β”œβ”€{wtq}(2823)
          β”œβ”€{wtq}(2824)
          β”œβ”€{wtq}(2825)
          β”œβ”€{wtq}(2826)
          β”œβ”€{wtq}(2827)
          β”œβ”€{wtq}(2828)
          β”œβ”€{wtq}(2829)
          β”œβ”€{wtq}(2830)
          β”œβ”€{wtq}(2831)
          β”œβ”€{wtq}(2832)
          β”œβ”€{wtq}(2833)
          β”œβ”€{wtq}(2834)
          β”œβ”€{wtq}(2835)
          β”œβ”€{wtq}(2837)
          β”œβ”€{wtq}(2840)
          β”œβ”€{wtq}(2841)
          β”œβ”€{wtq}(2842)
          β”œβ”€{wtq}(2843)
          β”œβ”€{wtq}(2844)
          β”œβ”€{wtq}(2845)
          β”œβ”€{wtq}(2846)
          β”œβ”€{wtq}(2847)
          β”œβ”€{wtq}(2848)
          β”œβ”€{wtq}(2855)
          β”œβ”€{wtq}(2907)
          β”œβ”€{wtq}(3002)
          β”œβ”€{wtq}(3062)
          β”œβ”€{wtq}(3063)
          β”œβ”€{wtq}(3064)
          β”œβ”€{wtq}(3065)
          β”œβ”€{wtq}(3078)
          β”œβ”€{wtq}(3080)
          β”œβ”€{wtq}(3084)
          β”œβ”€{wtq}(21709)
          β”œβ”€{wtq}(22012)
          β”œβ”€{wtq}(22627)
          β”œβ”€{wtq}(22889)
          └─{wtq}(22997)

And here's what the process tabs shows me in System Monitor: Image

For completeness sake, here's what Mission Center says: Image

nabaxo avatar Dec 02 '25 14:12 nabaxo

Thank you!

So:

- wtq           144MB
- wezterm-gui   331MB
- zsh            11MB
---------------------
- WTQ           486MB

Do you agree that the higher number of 486MB comes from the sum of wtq + all underlying processes, and that we seem to be at a stable ~150MB for wtq only? In other words, that wtq without GUI hovers around 150MB?

If so, we can further scope to wtqs memory usage, and consider the wild memory usage differences on process groups.

Secondly, if you do agree with the above, can you give me your thoughts on what you find acceptable for (a program like) wtq?

Of course, 150MB for a small thing in the background is kinda bulky, but given the probably effort I'm leaning towards considering ~150MB a reasonable target for now.

flyingpie avatar Dec 02 '25 15:12 flyingpie

Honestly, after this digging, 150 mb is fine for a program written in something like C#; like it's wildly high for some other programming languages, but I can live with 150 mb.

nabaxo avatar Dec 02 '25 15:12 nabaxo

Totally agree there, thanks! I'm looking for a proper goal for this particular issue, to scope things a bit.

That means for now, the goal is to keep the average usage around 150MB, which means separating the GUI in some way.

Later, we can look into more avenues, maybe AOT can help.

Thank you again for all your help, really appreciate it!

flyingpie avatar Dec 02 '25 15:12 flyingpie