http://virtualthreads.blogspot.jp/2006/02/understanding-memory-usage-on-linux.html
因为是google blog,可能要翻墙
What ps reports
For example, here is the output of ps aux for KEdit on my computer:
这是我机器上KEdit 在ps aux 下的使用情况
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
dbunker 3468 0.0 2.7 25400 14452 ? S 20:19 0:00 kdeinit: kedit
According to ps, KEdit has a virtual size of about 25 megabytes and a resident size of about 14 megabytes (both numbers above are reported in kilobytes).
根据ps,KEdit使用了25M的虚拟内存和14M的物理内存
Why ps is "wrong"
为什么ps是“错的”
Depending on how you look at it, ps is not reporting the real memory usage of processes.
关键在于你怎样看,ps并没有报告进程真实的内存使用量
What it is really doing is showing how much real memory each process would take up if it were the only process running.
ps做的只是显示了当只有它一个进程在运行时需要使用的真实的内存量
Of course, a typical Linux machine has several dozen processes running at any given time, which means that the VSZ and RSS numbers reported by ps are almost definitely "wrong".
当然,linux机器中任何时间都会有一打子进程在运行,所以ps的对VSZ和RSS的报告几乎都是”错的”.
In order to understand why, it is necessary to learn how Linux handles shared libraries in programs.
为了理解,有必要明白linux在程序中怎样处理共享库.
Most major programs on Linux use shared libraries to facilitate certain functionality.
linux中的许多主流程序都会使用共享库来实现一些功能
For example, a KDE text editing program will use several KDE shared libraries (to allow for interaction with other KDE components),
比如KDE文字处理程序会使用几个KDE共享程序(为了KDE部件之间的的交流)
several X libraries (to allow it to display images and copy and pasting),
几个X库(使得可以显示图片;可以复制粘贴)
and several general system libraries (to allow it to perform basic operations).
和几个通用的系统库(允许一些基本操作)
Many of these shared libraries, especially commonly used ones like libc, are used by many of the programs running on a Linux system.
其中的许多共享库,特别是类似与libc的,在linux系统中都会被共同使用.
Due to this sharing, Linux is able to use a great trick: it will load a single copy of the shared libraries into memory and use that one copy for every program that references it.
因为共享,linux会使用一个技巧:它只会把一份共享库的拷贝加载到内存中,而让每个程序都使用它
For better or worse, many tools don't care very much about this very common trick;
不管你怎么想,反正许多程序并不关心linux中的这个技巧
they simply report how much memory a process uses, regardless of whether that memory is shared with other processes as well.
它们只是报告一个进程使用了多少内存,而不管内存是不是被其它进程共享
Two programs could therefore use a large shared library and yet have its size count towards both of their memory usage totals;
因此两个程序可以使用很大的共享库,而且只在乎自己总共使用了多少内存
the library is being double-counted, which can be very misleading if you don't know what is going on.
所以库被重数了两次,如果不知道的话真的会很疑惑
Unfortunately, a perfect representation of process memory usage isn't easy to obtain.
遗憾的是并没有一个完美的方法来显示进程的实际内存使用量
Seeing a process's memory map
To see what KEdit's memory looks like, we'll use the pmap program (with the -d flag):
让我们来用pmap程序(-d 选项)看看KEdit的内存使用吧
程序代码:
Address Kbytes Mode Offset Device Mapping
08048000 40 r-x-- 0000000000000000 0fe:00000 kdeinit
08052000 4 rw--- 0000000000009000 0fe:00000 kdeinit
08053000 1164 rw--- 0000000008053000 000:00000 [ anon ]
40000000 84 r-x-- 0000000000000000 0fe:00000 ld-2.3.5.so
40015000 8 rw--- 0000000000014000 0fe:00000 ld-2.3.5.so
40017000 4 rw--- 0000000040017000 000:00000 [ anon ]
40018000 4 r-x-- 0000000000000000 0fe:00000 kedit.so
40019000 4 rw--- 0000000000000000 0fe:00000 kedit.so
40027000 252 r-x-- 0000000000000000 0fe:00000 libkparts.so.2.1.0
40066000 20 rw--- 000000000003e000 0fe:00000 libkparts.so.2.1.0
4006b000 3108 r-x-- 0000000000000000 0fe:00000 libkio.so.4.2.0
40374000 116 rw--- 0000000000309000 0fe:00000 libkio.so.4.2.0
40391000 8 rw--- 0000000040391000 000:00000 [ anon ]
40393000 2644 r-x-- 0000000000000000 0fe:00000 libkdeui.so.4.2.0
40628000 164 rw--- 0000000000295000 0fe:00000 libkdeui.so.4.2.0
40651000 4 rw--- 0000000040651000 000:00000 [ anon ]
40652000 100 r-x-- 0000000000000000 0fe:00000 libkdesu.so.4.2.0
4066b000 4 rw--- 0000000000019000 0fe:00000 libkdesu.so.4.2.0
4066c000 68 r-x-- 0000000000000000 0fe:00000 libkwalletclient.so.1.0.0
4067d000 4 rw--- 0000000000011000 0fe:00000 libkwalletclient.so.1.0.0
4067e000 4 rw--- 000000004067e000 000:00000 [ anon ]
4067f000 2148 r-x-- 0000000000000000 0fe:00000 libkdecore.so.4.2.0
40898000 64 rw--- 0000000000219000 0fe:00000 libkdecore.so.4.2.0
408a8000 8 rw--- 00000000408a8000 000:00000 [ anon ]
... (trimmed) ...
mapped: 25404K writeable/private: 2432K shared: 0K
08048000 40 r-x-- 0000000000000000 0fe:00000 kdeinit
08052000 4 rw--- 0000000000009000 0fe:00000 kdeinit
08053000 1164 rw--- 0000000008053000 000:00000 [ anon ]
40000000 84 r-x-- 0000000000000000 0fe:00000 ld-2.3.5.so
40015000 8 rw--- 0000000000014000 0fe:00000 ld-2.3.5.so
40017000 4 rw--- 0000000040017000 000:00000 [ anon ]
40018000 4 r-x-- 0000000000000000 0fe:00000 kedit.so
40019000 4 rw--- 0000000000000000 0fe:00000 kedit.so
40027000 252 r-x-- 0000000000000000 0fe:00000 libkparts.so.2.1.0
40066000 20 rw--- 000000000003e000 0fe:00000 libkparts.so.2.1.0
4006b000 3108 r-x-- 0000000000000000 0fe:00000 libkio.so.4.2.0
40374000 116 rw--- 0000000000309000 0fe:00000 libkio.so.4.2.0
40391000 8 rw--- 0000000040391000 000:00000 [ anon ]
40393000 2644 r-x-- 0000000000000000 0fe:00000 libkdeui.so.4.2.0
40628000 164 rw--- 0000000000295000 0fe:00000 libkdeui.so.4.2.0
40651000 4 rw--- 0000000040651000 000:00000 [ anon ]
40652000 100 r-x-- 0000000000000000 0fe:00000 libkdesu.so.4.2.0
4066b000 4 rw--- 0000000000019000 0fe:00000 libkdesu.so.4.2.0
4066c000 68 r-x-- 0000000000000000 0fe:00000 libkwalletclient.so.1.0.0
4067d000 4 rw--- 0000000000011000 0fe:00000 libkwalletclient.so.1.0.0
4067e000 4 rw--- 000000004067e000 000:00000 [ anon ]
4067f000 2148 r-x-- 0000000000000000 0fe:00000 libkdecore.so.4.2.0
40898000 64 rw--- 0000000000219000 0fe:00000 libkdecore.so.4.2.0
408a8000 8 rw--- 00000000408a8000 000:00000 [ anon ]
... (trimmed) ...
mapped: 25404K writeable/private: 2432K shared: 0K
One important thing to note about the output is that each shared library is listed twice;
很重要的一点是共享库都被列出了两次
once for its code segment and once for its data segment.
一次是代码段,一次是数据段
The code segments have a mode of "r-x--", while the data is set to "rw---".
代码段被设为”r-x--”,数据段被设为”rx---”
The Kbytes, Mode, and Mapping columns are the only ones we will care about, as the rest are unimportant to the discussion.
Kbytes ,Mode, Mapping列是需要注意的
If you go through the output, you will find that the lines with the largest Kbytes number are usually the code segments of the included shared libraries (the ones that start with "lib" are the shared libraries).
你会发现Kbytes列有很大数值的都是共享库的代码段
What is great about that is that they are the ones that can be shared between processes.
它们其实都是被很多进程所共享的
If you factor out all of the parts that are shared between processes, you end up with the "writeable/private" total, which is shown at the bottom of the output.
输出最底下的”wrieable/private”
Therefore, the cost to run this instance of KEdit (assuming that all of the shared libraries were already loaded) is around 2 megabytes.
因此,运行KEdit(假设所有共享库都被加载)实际使用2M左右的内存
That is quite a different story from the 14 or 25 megabytes that ps reported.
而不是ps中报告的14或者25
If you run KDE for your desktop, but mostly use Gnome applications, then you are paying a large price for a lot of redundant (but different) shared libraries.
建议:如果你运行KDE界面,却使用大量的Gnome程序,你要付出的代价就是过多的(却不重复的)共享库
By sticking to just KDE or just Gnome apps as much as possible.
所以只选择使用KDE或是Gnome程序
[ 本帖最后由 madfrogme 于 2012-7-20 18:32 编辑 ]