Extremely large "VIRT" memory usage reported by `top`

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:

enter image description here

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?".

0

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:

ThreadMemory Reported
1590MB
2410MB
3200MB
4650MB
5150MB
625MB
740MB
835MB
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:

ThreadMemory ReportedActual
1590MB590MB
(590 - 0 = 590)
2410MB35MB
(410 - 375 = 35)
4650MB275MB
(650 - 375 = 275)
Total:1,650MB900MB

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:

  1. How can Discord be using 40 gigs, teams 13 gigs, and zulip 36 gigs of virtual memory?
    ⇢ See above.

  2. 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-max

    On 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-max

    There 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 ulimit and getrlimit.

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.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like