On Ubuntu 20.04.4 LTS, on a machine which is a few years old. The attached screenshot of the output of top strikes me as really odd:
I have a regular PC (nothing fancy) with 16 gigs of ram and no swap. How can Discord be using 40 gigs, teams 13 gigs, and zulip 36 gigs of virtual memory? I have occasional memory management problems with this machine right now; sometimes if I'm using some software called Lean which uses a lot of threads then it can make the machine unresponsive and I need to use SysRq to recover; I don't have this trouble running Lean on any of my other Ubuntu devices with similar specs. Is this machine borked in some way?
Edit: I've been asked to clarify what the question is. It is "My machine randomly grinds to a halt quite often; it becomes unresponsive and I have to get the kernel to randomly kill processes to make it responsive again. I look at the figures in the screenshot (standard well-known apps taking up 40 gigs of virtual memory) and something strikes me as extremely odd about them. Can anyone else confirm that top claims that their Discord is taking up 40 gigs of virtual memory?".
1 Answer
Virtual memory and physical memory are quite different. This wiki article can give you a pretty good rundown of how virtual memory works, but the gist of it is like this:
Virtual memory an abstracted memory space that includes physical and cached storage. Because it is abstracted by the operating system, applications are able to share libraries and other objects across threads (and sometimes with other applications).
The amount of Virtual memory consumed can sometimes confuse people for the very reason that you've identified. Discord, logically speaking, cannot be using 40GB of memory when your system has just 16GB available. However, the calculation used to determine how much virtual memory a process is using works more like this:
Memory Used = Reported memory consumption of each thread in a process
So, assuming a process is running with 8 threads, the system might see something like this:
| Thread | Memory Reported |
|---|---|
| 1 | 590MB |
| 2 | 410MB |
| 3 | 200MB |
| 4 | 650MB |
| 5 | 150MB |
| 6 | 25MB |
| 7 | 40MB |
| 8 | 35MB |
| Total: | 2.1GB |
However, each of these threads will be sharing some of the same memory. Threads 1, 2, and 4 may be using the same 375MB of libraries, which would result in top (and other tools) showing 1.65GB of memory being used when, in reality, it's just 900MB:
| Thread | Memory Reported | Actual |
|---|---|---|
| 1 | 590MB | 590MB (590 - 0 = 590) |
| 2 | 410MB | 35MB (410 - 375 = 35) |
| 4 | 650MB | 275MB (650 - 375 = 275) |
| Total: | 1,650MB | 900MB |
When you run applications that use dozens or hundreds of threads, this math can rapidly result in virtual memory figures that appear to be an order of magnitude higher than the amount of installed RAM. For well-designed applications, this isn't an issue, and Linux is capable of addressing up to 16EB of virtual memory so there is little chance that your system will reach this amount without running an application that has millions of threads that each consume the same shared memory space.
Note that the "memory used" calculation takes the reported amount of memory being used by a thread. Threads generally do not know how much memory they are sharing with others.
With this bit of math out of the way, let's look at your questions:
How can Discord be using 40 gigs, teams 13 gigs, and zulip 36 gigs of virtual memory?
⇢ See above.I have occasional memory management problems with this machine right now; sometimes if I'm using some software called Lean which uses a lot of threads then it can make the machine unresponsive and I need to use SysRq to recover; I don't have this trouble running Lean on any of my other Ubuntu devices with similar specs. Is this machine borked in some way?
⇢ How many is "a lot"? Linux does have a limit on the total number of processes/threads that can run on a system, and you can find this number for your computer via the terminal like this:cat /proc/sys/kernel/threads-maxOn my personal notebook, a Lenovo X1 Carbon with an older Core i5 and 8GB of RAM, I get a value of
62361. By default, this number is calculated as the number of memory pages divided by 4.I am unfamiliar with Lean but, if the application is making tens of thousands of threads and overwhelming the operating system to the point where the kernel begins killing threads, then you can temporarily increase the thread maximum like this:
echo 131072 > /proc/sys/kernel/threads-maxThere is also a total limit on the number of processes/threads a single user can create so, if you're really pushing your system with threads, you'll want to examine
ulimitandgetrlimit.
As a final note:
I have a regular PC (nothing fancy) with 16 gigs of ram and no swap.
That lack of swap is going to create issues if you're running applications that generate thousands of threads. If the goal is to reduce SSD wear, then not having a swap will do little to help. Your applications can still write to cache and tmp locations, which will be written to disk. A system with thousands of threads reading/writing to cache is no different from a system that uses swap when the physical memory becomes exhausted. A lack of swap will also create issues in the event that you are working with a lot of files, as each open file requires a little bit of memory.
Your system would likely benefit from having a small amount of swap allocated, perhaps 4~8GB, and a vm.swappiness value somewhere between 5 and 15 to ensure the system uses the RAM as much as possible.