Linux Virtual Memory Question

Hello,
I am trying to understand the VIRT field that shows in the TOP command output. I have a users application that appears to be leaking memory. I see that the field VIRT in the top output is showing 55.8g.

The question is where is that getting stored? The disk does not appear to have that much space used on it. An the system only has 24GB of ram. Is this a combination of RAM and DISK? Here is some examples.

[root@MWET66 ~]# df -kh
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda3              64G   22G   40G  36% /
/dev/sda1              99M   12M   83M  13% /boot
tmpfs                  12G     0   12G   0% /dev/shm
top - 12:36:53 up 21:13,  2 users,  load average: 0.18, 0.28, 0.22
Tasks: 171 total,   1 running, 170 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.6%us,  0.0%sy,  0.0%ni, 99.2%id,  0.0%wa,  0.0%hi,  0.2%si,  0.0%st
Mem:  24675472k total, 23320044k used,  1355428k free,    13912k buffers
Swap:  2096472k total,  2096472k used,        0k free,   195040k cached
PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                                                         
24797 user   18   0 55.8g  21g 121m S  5.0 92.7  22:59.38 application

Any help would be appreciated.

jaysunn

Virtual memory is virtual. If the application doesn't actually use it, it doesn't get stored anywhere at all.

More interesting is the RES field, the memory the application's actually managed to get paged in and used.

ok...in that case, what is the real interpretation of virtual memory value shown with top command ?

man page says:

 VIRT  --  Virtual Image (kb)
          The total amount of virtual memory used by the task.  It includes all code, data and shared libraries plus pages that have been swapped out. (Note: you can define the STATSIZE=1 environment variable and
          the VIRT will be calculated from the /proc/#/state VmSize field.)

You might be confusing with allocated memory.
Virtual memory as reported by top is the sum of memory present either on disk (mostly SWAP) or on RAM (RES).

I beg to differ:

$ cat megaalloc.c
#include <stdio.h>
#include <unistd.h>

int main(void)
{
	sbrk((1024L*1024L*1024L));
	while(1);
}
$ gcc megaalloc.c
$ ./a.out
top - 17:46:55 up  6:12,  4 users,  load average: 0.24, 0.17, 0.11
Tasks: 127 total,   2 running, 124 sleeping,   0 stopped,   1 zombie
Cpu(s): 45.5%us,  3.5%sy,  0.0%ni, 48.2%id,  0.3%wa,  2.5%hi,  0.0%si,  0.0%st
Mem:   3797432k total,  3236628k used,   560804k free,   161272k buffers
Swap:  2104476k total,        0k used,  2104476k free,  1373932k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND            
10599 monttyle  20   0 1027m  296  228 R   73  0.0   0:02.19 a.out              
 3825 root      20   0  748m  82m  10m S    8  2.2  25:52.57 X                  
10017 monttyle  20   0  149m 8032 5936 S    8  0.2   3:49.15 mplayer            
 9712 monttyle  20   0  220m  15m  10m S    5  0.4   4:38.51 gnome-terminal     
 5988 monttyle  20   0 1591m 1.3g  26m S    3 37.0  52:49.71 firefox-bin        
 9710 monttyle  20   0 71692  13m 4900 S    2  0.4   3:03.59 wish               
 5256 monttyle  20   0  216m  14m  10m S    1  0.4   2:54.01 metacity           
    8 root      20   0     0    0    0 S    0  0.0   0:10.05 events/1           
  453 root      20   0     0    0    0 S    0  0.0   1:20.78 kondemand/1        
 5278 monttyle  20   0  346m  23m  15m S    0  0.6   4:30.59 gnome-panel        
    1 root      20   0  3892  620  516 S    0  0.0   0:01.42 init               
    2 root      20   0     0    0    0 S    0  0.0   0:00.00 kthreadd           
    3 root      RT   0     0    0    0 S    0  0.0   0:00.06 migration/0        
    4 root      20   0     0    0    0 S    0  0.0   0:00.42 ksoftirqd/0        
    5 root      RT   0     0    0    0 S    0  0.0   0:00.01 migration/1        
    6 root      20   0     0    0    0 S    0  0.0   0:02.82 ksoftirqd/1        
    7 root      20   0     0    0    0 S    0  0.0   0:07.20 events/0

My process certainly does not have 1027M resident. It doesn't have it on disk, either -- having not used any of that gig of ram, none of it is actually paged in, resident, or even backed in any form. Other systems might demand sufficient swap to back it but not Linux, which by default has virtual swap.

On a 64-bit system you can also inflate that value by plunking in your entire hard disk as a memory segment via mmap. 300G virtual. I suppose that would count as on disk though.

I stand corrected. Top correctly reports allocated memory including overcommitted one.

The top original manual page (top(1) - The UNIX and Linux Forums ) is confusing as this 1 GiB is not made of pages that have been swapped out but pages that were never used in in the first place.

Debian top manual page has this part corrected:

VIRT  --  Virtual Image (kb)
          The total amount of virtual memory used by the task.  It includes all
          code, data and shared libraries plus pages  that have been swapped out
          and pages that have been mapped but not used.

Linux doesn't have "virtual swap", but by default Linux does overcommit swap space - IMO a REALLY, REALLY BAD IDEA.

Because eventually it's going to get used. Which means the OOM killer is going to wake up and start randomly killing processes, aiming for heavy memory users.

You know - the processes like web servers and databases that are the actual reason you're using the computer in the first place.

"Works most of the time, then goes BOOM!" is an awfully low reliability standard.

That wouldn't usually need swap space because the backing store for the virtual memory would be your hard disk you mmap()'d, but you could probably map it in such a way that if you were to write to it, the changed pages would require swap backing. Maybe by mmap()'ing a read-only file descriptor read/write?

I've heard it referred to as virtual swap, and took it as another term for it...

A gridlocked system with insufficient RAM for kill -9 rameater is a tough nut to crack too, with the same fix as the oom-killer: "Don't let it happen". That's why there's programmable limits for these things.

I'll note that Linux systems tend to be poorly configured for swap in general, it's mostly considered a 'quick fix' for brief low-ram/high load conditions... It gets thrown on the same spindle and forgotten. So if it gets used at all, performance truly goes down the toilet.

MAP_PRIVATE ought to do it.