Oct 04

VIRT stands for the virtual size of a process, which is the sum of memory it is actually using, memory it has mapped into itself (for instance the video card’s RAM for the X server), files on disk that have been mapped into it (most notably shared libraries), and memory shared with other processes. VIRT represents how much memory the program is able to access at the present moment.

RES stands for the resident size, which is an accurate representation of how much actual physical memory a process is consuming. (This also corresponds directly to the %MEM column.) This will virtually always be less than the VIRT size, since most programs depend on the C library.

SHR indicates how much of the VIRT size is actually sharable (memory or libraries). In the case of libraries, it does not necessarily mean that the entire library is resident. For example, if a program only uses a few functions in a library, the whole library is mapped and will be counted in VIRT and SHR, but only the parts of the library file containing the functions being used will actually be loaded in and be counted under RES.

written by MG

27 Responses to “The difference among VIRT, RES, and SHR in top output”

  1. 1. Nick Says:

    I’ve been asked this question on many job interviews and have seen it asked many times and have since started asking it when I interview people. Many people don’t have a clear understanding of these differences. Your article summed it up in a very clean, straight forward manner. Thanks!

  2. 2. upen Says:

    Thank you! Very useful and clear

  3. 3. Zane Kolnik Says:

    Hold on so are you saying that this:
    22120 apache 15 0 317m 31m 4468 S 0.0 1.8 0:00.69 httpd

    means one apache http request is using 317MB of ram total and 31MB allocated to the httpd request?

    That seems like alot!

  4. 4. hash Says:

    how about DATA and CODE? and why DATA + CODE RES?

  5. 5. gilm Says:

    thanks a lot! 🙂

  6. 6. maxl Says:

    Zane Kolnik has an interesting question i’m trying to find the answer to. Those columns, RES, VIRT and SHR sometimes have the ‘m’ character appended to the end of the value; does this mean “million” or “megebytes”? none of those sounds right. the man page says those values are in kb, but 317’million’ kb doesn’t make sense.

  7. 7. Victor Says:

    maxl: The ‘m’ stands for ‘mega’. (Note the ‘a’ at the end.)

    If you have a process take up enough memory, it will have a ‘g’ as the suffix, as in ‘giga’.

  8. 8. ddekany Says:

    SHR in fact doesn’t reliably show how much of VIRT is shareable, as it doesn’t account for the IPC mechanism called shared memory (SHM). This gives a huge error for example with “postgres” processes, where most of VIRT is taken by the big chunk of writable shared memory that all “postgres” processes share. So, if you have a connection pool of 4 connections, you will constantly see 4 “postgres” processes, each with, let’s say, 50 MB of VIRT size and only 5M of SHR, and you believe these then eat up (50 VIRT – 5 SHR) * 4 = 180 MB-s, where in fact they only eat up (50 VIRT – 38 SHM – 5 SHR) * 4 + 38 SHM = 66 MB.

    (BTW, this reply form is a crap. Not only it doesn’t re-fill the form for you when there’s something to fix, when stepping back after the error message it somehow manages to prevent FireFox from restoring its earlier content…)

  9. 9. bioknight Says:

    Nice review. Does the VIRT column corresponds to the Memory cached and buffer size?

  10. 10. Juhi Says:

    I don’t observe as you said in your brief…

    top – 22:17:11 up 3 days, 8:55, 3 users, load average: 3.27, 2.97, 2.73
    Tasks: 357 total, 1 running, 356 sleeping, 0 stopped, 0 zombie
    Cpu(s): 0.3%us, 0.2%sy, 0.0%ni, 99.5%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
    Mem: 32948176k total, 22265536k used, 10682640k free, 444016k buffers
    Swap: 0k total, 0k used, 0k free, 15811124k cached

    8184 root 20 0 198m 30m 2668 S 1 0.1 11:20.61 ovldMgr
    15 root 20 0 0 0 0 S 0 0.0 0:35.87 softirq-timer/1
    4817 mysql 20 0 2066m 443m 7236 S 0 1.4 49:47.21 mysqld
    6713 root 20 0 35476 5924 1012 S 0 0.0 73:54.90 mlogd

    7294 root 20 0 1436m 1.1g 3492 S 0 3.5 4:26.07 mcmserver

    See what I observe for mcmserver (its an app) …so what g represents in 1.1g, gigabytes?? Then your second point is not valid..right. I need to know what does it actually represents as even with this memory usage I dont see any difference in the this app works

  11. 11. Jhorghex Says:

    re newer kernels I beleive it still is a problem. Nevertheless it would be good to test yourself if you have access to a many-core box.joe it would be very interesting to see if this is what you’re bumping into. Can you try some of the tests I outlined on that web page?I too thought it was a numa issue but I think it’s more of an issue handling all the locking on the different memory sections one needs to traverse with a lot of cores. While it turns out you can’t have a lot of cores without a lot of sockets and hence NUMA, it’s not really the numa code that is doing this. At least that’s my understanding.-mark

  12. 12. sangvv Says:

    Hi all,
    I have program, when i run it and check using top command that have some info:

    3723 root 20 0 21.8g 316m 13m S 0.0 1.0

    I run in: Linux localhost.localdomain 2.6.32-300.3.1.el6uek.x86_64 #1 SMP Fri Dec 9 18:57:35 EST 2011 x86_64 x86_64 x86_64 GNU/Linux
    With 32g memory.

    Show i think the VIRT so Big, can have any one give me some suggesstion.

    Thank & Regards

  13. 13. Gerry Says:

    Thanks for the helpful guide, however can you describe more about SHR (shared). At what point a proportion of memory is determined to be shared. If I’m writing a library of my own — is there a way to utilize this shared memory?

  14. 14. Senny Says:

    Hope this helps..

    a: PID — Process Id
    The task’s unique process ID, which periodically wraps, though
    never restarting at zero.

    b: PPID — Parent Process Pid
    The process ID of a task’s parent.

    c: RUSER — Real User Name
    The real user name of the task’s owner.

    d: UID — User Id
    The effective user ID of the task’s owner.

    e: USER — User Name
    The effective user name of the task’s owner.

    f: GROUP — Group Name
    The effective group name of the task’s owner.

    g: TTY — Controlling Tty
    The name of the controlling terminal. This is usually the
    device (serial port, pty, etc.) from which the process was
    started, and which it uses for input or output. However, a
    task need not be associated with a terminal, in which case
    you’ll see ‘?’ displayed.

    h: PR — Priority
    The priority of the task.

    i: NI — Nice value
    The nice value of the task. A negative nice value means higher
    priority, whereas a positive nice value means lower priority.
    Zero in this field simply means priority will not be adjusted
    in determining a task’s dispatchability.

    j: P — Last used CPU (SMP)
    A number representing the last used processor. In a true SMP
    environment this will likely change frequently since the kernel
    intentionally uses weak affinity. Also, the very act of
    running top may break this weak affinity and cause more
    processes to change CPUs more often (because of the extra
    demand for cpu time).

    k: %CPU — CPU usage
    The task’s share of the elapsed CPU time since the last screen
    update, expressed as a percentage of total CPU time. In a true
    SMP environment, if ‘Irix mode’ is Off, top will operate in
    ‘Solaris mode’ where a task’s cpu usage will be divided by the
    total number of CPUs. You toggle ‘Irix/Solaris’ modes with the
    ‘I’ interactive command.

    l: TIME — CPU Time
    Total CPU time the task has used since it started. When
    ‘Cumulative mode’ is On, each process is listed with the cpu
    time that it and its dead children has used. You toggle
    ‘Cumulative mode’ with ‘S’, which is a command-line option and
    an interactive command. See the ‘S’ interactive command for
    additional information regarding this mode.

    m: TIME+ — CPU Time, hundredths
    The same as ‘TIME’, but reflecting more granularity through
    hundredths of a second.

    n: %MEM — Memory usage (RES)
    A task’s currently used share of available physical memory.

    o: 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

    p: SWAP — Swapped size (kb)
    Memory that is not resident but is present in a task. This is
    memory that has been swapped out but could include additional
    non-resident memory. This column is calculated by subtracting
    physical memory from virtual memory.

    q: RES — Resident size (kb)
    The non-swapped physical memory a task has used.

    r: CODE — Code size (kb)
    The amount of virtual memory devoted to executable code, also
    known as the ‘text resident set’ size or TRS.

    s: DATA — Data+Stack size (kb)
    The amount of virtual memory devoted to other than executable
    code, also known as the ‘data resident set’ size or DRS.

    t: SHR — Shared Mem size (kb)
    The amount of shared memory used by a task. It simply reflects
    memory that could be potentially shared with other processes.

    u: nFLT — Page Fault count
    The number of major page faults that have occurred for a task.
    A page fault occurs when a process attempts to read from or
    write to a virtual page that is not currently present in its
    address space. A major page fault is when backing storage
    access (such as a disk) is involved in making that page

    v: nDRT — Dirty Pages count
    The number of pages that have been modified since they were
    last written to disk. Dirty pages must be written to disk
    before the corresponding physical memory location can be used
    for some other virtual page.

    w: S — Process Status
    The status of the task which can be one of:
    ‘D’ = uninterruptible sleep
    ‘R’ = running
    ‘S’ = sleeping
    ‘T’ = traced or stopped
    ‘Z’ = zombie

    Tasks shown as running should be more properly thought of as
    ‘ready to run’ — their task_struct is simply represented on
    the Linux run-queue. Even without a true SMP machine, you may
    see numerous tasks in this state depending on top’s delay
    interval and nice value.

  15. 15. Harishankar Says:

    Awesome summary man !!! Just the basics but clearly written.

  16. 16. Claudiu Says:

    @sangvv: if your program has some hundred or thousand of threads, virt will be increased in such way. It doesn’t means that it consume such a big value. The program requested the addresses in memory, but it didn’t consume that much.

    I had a situation where I had to make a program with 1000 threads and VIRT was the entire address space(4G), but it consumed only 100MB.

  17. 17. charles Says:

    @MG. Very well done post. Also some very informative answers and comments by others. Also the response by Senny added additional clarity. Well done all!

  18. 18. Doug Says:

    What does this mean then:
    5921 dnapoleo 20 0 2499m 2.3g 2.1g S 0.0 4.9 0:30.79 python

    I have my process blocking on user input, and this is remaining constant. In truth, 2.1GB is shared, and 240Meg is not. RES is reporting private + shared memory for me. But not always. Sometimes it appears to not represent the SHR portion. Why?

  19. 19. Shiv Says:

    If I want to check whether a process is leaking memory, then looking at RES and %MEM over a period of time for that process should be sufficient? Please let me know.

    I have a case where the RES and %MEM over a 24 period remained the same but the VIRT has grown from 49m to 119m!

  20. 20. vijay Says:

    Can someone explain how do we evaluate VIRT, g is obviously not Gig.

    top – 09:58:15 up 38 days, 8:37, 2 users, load average: 1.03, 1.08, 0.97
    Tasks: 914 total, 3 running, 911 sleeping, 0 stopped, 0 zombie
    Cpu(s): 20.7%us, 8.3%sy, 0.0%ni, 64.2%id, 0.0%wa, 0.0%hi, 6.8%si, 0.0%st
    Mem: 264493616k total, 242594532k used, 21899084k free, 145400k buffers
    Swap: 33554428k total, 0k used, 33554428k free, 223535976k cached

    4152 aaaaaaaa 20 0 53.9g 5.5g 87m S 919.9 2.2 11742:41 java
    14365 aaaaaaaa 20 0 113m 11m 844 R 75.0 0.0 0:02.28 lsof
    14138 aaaaaaaa 20 0 3234m 213m 11m S 57.9 0.1 0:13.88 java
    14375 aaaaaaaa 20 0 102m 204 76 R 34.9 0.0 0:01.06 lsof
    3903 root 20 0 4079m 103m 5100 S 3.6 0.0 1184:17 ds_am
    59917 aaaaaaaa 20 0 6691m 841m 5308 S 1.6 0.3 562:07.17 java
    8494 aaaaaaaa 20 0 17788 1940 952 R 1.3 0.0 0:08.54 top

  21. 21. vijay Says:

    Before I comment about my own question.
    I have got the answer, but people in this thread may comment.
    g is not Gigabyte it is Gigabit
    m is not megabyte it is megabeit
    M – megabyte
    G – Gigabyte
    So, 53.9g is 6.7375 Gigabit (Gig)

  22. 22. Brendan Says:

    No it isn’t bits. It is bytes

  23. 23. Sat Says:

    I think you are wrong,

    VIRT could be physical memory + swap

    I do not see in top manual
    from where you have got it?

  24. 24. Stu Says:

    I guess it’s worth noting you can toggle between top’s mem usage formats by repeatedly pressing E or e, for the summary and task areas respectively.
    And W will write your prefs to .toprc.

  25. 25. Loner Says:

    VIRT : Size in memory of the total program size.
    RES : The resident set size, i.e the size of the text and data sections, plus stack usage.
    SHR : The size of the process’s shared pages.

    welcome to my website http://www.z-dig.com

  26. 26. roger Says:

    Note also that VIRT can mean mapped but *not yet used* memory for a process, so isn’t always an awesome way to tell how much “real” RAM a process is using.

  27. 27. Binh Thanh Nguyen Says:

    Thanks, nice post

Leave a Reply