在Linux中用ps命令看到的每个进程使用的内存是该进程所用到的内存之和,是假定当系统只有该进程运行时,该进程使用的内存。
之所以用ps看的内存报告是“错误的”是因为Linux系统对共享库的处理。系统只装载一份共享库代码,所有使用该库的进程都可以在自己的地址空间中访问到该共享库代码。
比如ps命令报告每个Apache进程可能都用了10M内存,而实际上每个进程的边际代价为1M内存,其余9M是在所有的Apache进程之间共享的。
http://virtualthreads.blogspot.com/2006/02/understanding-memory-usage-on-linux.html
Understanding memory usage on Linux
This entry is for those people who have ever wondered, "Why the hell is a simple KDE text editor taking up 25 megabytes of memory?" Many people are led to believe that many Linux applications, especially KDE or Gnome programs, are "bloated" based solely upon what tools like ps report. While this may or may not be true, depending on the program, it is not generally true -- many programs are much more memory efficient than they seem.
What ps reports
The ps tool can output various pieces of information about a process, such as its process id, current running state, and resource utilization. Two of the possible outputs are VSZ and RSS, which stand for "virtual set size" and "resident set size", which are commonly used by geeks around the world to see how much memory processes are taking up.
For example, here is the output of ps aux for KEdit on my computer:
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). It seems that most people like to randomly choose to accept one number or the other as representing the real memory usage of a process. I'm not going to explain the difference between VSZ and RSS right now but, needless to say, this is the wrong approach; neither number is an accurate picture of what the memory cost of running KEdit is.
Why ps is "wrong"
Depending on how you look at it, ps is not reporting the real memory usage of processes. What it is really doing is showing how much real memory each process would take up if it were the only process running. 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". In order to understand why, it is necessary to learn how Linux handles shared libraries in programs.
Most major programs on Linux use shared libraries to facilitate certain functionality. For example, a KDE text editing program will use several KDE shared libraries (to allow for interaction with other KDE components), several X libraries (to allow it to display images and copy and pasting), 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. 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.
For better or worse, many tools don't care very much about this very common trick; 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. Not only do you need to understand how the system really works, but you need to decide how you want to deal with some hard questions. Should a shared library that is only needed for one process be counted in that process's memory usage? If a shared library is used my multiple processes, should its memory usage be evenly distributed among the different processes, or just ignored? There isn't a hard and fast rule here; you might have different answers depending on the situation you're facing. It's easy to see why ps doesn't try harder to report "correct" memory usage totals, given the ambiguity.
Seeing a process's memory map
Enough talk; let's see what the situation is with that "huge" KEdit process. To see what KEdit's memory looks like, we'll use the pmap program (with the -d flag):
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
I cut out a lot of the output; the rest is similar to what is shown. Even without the complete output, we can see some very interesting things. 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---". The Kbytes, Mode, and Mapping columns are the only ones we will care about, as the rest are unimportant to the discussion.
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). 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. This is what can be considered the incremental cost of this process, factoring out the shared libraries. Therefore, the cost to run this instance of KEdit (assuming that all of the shared libraries were already loaded) is around 2 megabytes. That is quite a different story from the 14 or 25 megabytes that ps reported.
What does it all mean?
The moral of this story is that process memory usage on Linux is a complex matter; you can't just run ps and know what is going on. This is especially true when you deal with programs that create a lot of identical children processes, like Apache. ps might report that each Apache process uses 10 megabytes of memory, when the reality might be that the marginal cost of each Apache process is 1 megabyte of memory. This information becomes critial when tuning Apache's MaxClients setting, which determines how many simultaneous requests your server can handle (although see one of my past postings for another way of increasing Apache's performance).
It also shows that it pays to stick with one desktop's software as much as possible. 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. By sticking to just KDE or just Gnome apps as much as possible, you reduce your overall memory usage due to the reduced marginal memory cost of running new KDE or Gnome applications, which allows Linux to use more memory for other interesting things (like the file cache, which speeds up file accesses immensely).
分享到:
相关推荐
在Linux系统中,内存池是一种优化内存管理的技术,尤其对于频繁分配和释放小块内存的情况,内存池可以显著提升性能并减少系统开销。本文将深入探讨Linux下的内存池实现,包括其原理、优势以及如何在C或C++中进行实践...
在Linux系统管理中,了解CPU和内存的使用情况是至关重要的。这不仅有助于日常的系统监控,还能在问题出现时迅速定位并解决。本文将详细介绍如何在Linux环境下使用`top`命令查看CPU使用率,以及如何利用`free`命令...
在Linux中,交换空间(Swap Space)是指硬盘上的一个区域,它用于存储内存中的数据,以便释放出内存空间供其他进程使用。当系统需要更多的内存时,系统会将暂时不用的内存块的内容写到交换空间中,以便释放出内存...
linux 共享内存简单使用
Python文件:python来查看Linux系统内存使用情况.py Python文件:python来查看Linux系统内存使用情况.py
针对linux内存的使用,详细讲解了如何优化内存,及性能的提高
通过简单的java程序测试Linux服务器内存使用、回收情况,排查Linux服务器内存使用异常的情况
操作系统随后处理这个中断,根据页表确定该页是否存在于磁盘上,如果是,则将其加载到物理内存中,并更新页表。 此外,Linux虚拟内存还包括内存压缩和透明大页(Transparent Huge Pages, THP)等高级特性。内存压缩...
本文将深入探讨嵌入式Linux内存使用与性能优化的相关知识点,帮助开发者更好地理解和改进其程序性能。 首先,理解Linux内存模型是优化的基础。Linux内核采用虚拟内存管理,包括物理内存(RAM)和交换空间(Swap)。...
linux 内核 内存泄露检测 linux 内核 内存泄露检测 linux 内核 内存泄露检测 linux 内核 内存泄露检测 linux 内核 内存泄露检测 linux 内核 内存泄露检测 linux 内核 内存泄露检测
为了监测内存使用情况,实验中使用了`free`和`vmstat`两个命令。`free`命令可以展示系统当前的内存使用状态,包括总内存、可用内存、缓冲区和缓存等。通过不同参数,如 `-b`, `-k`, `-m`, `-g`,可以以字节、千字节...
本书《嵌入式Linux内存使用与性能优化》主要围绕这两个问题进行了深入的探讨和分析。 内存使用方面,书中提出了两项核心任务:一是提高系统整体的空闲内存数量,从而提升进程的并发能力;二是在系统长时间运行后,...
本文将详细介绍如何使用mtrace工具来查找Linux中的内存泄露问题。 #### 二、mtrace工具简介 mtrace是一款功能强大的内存跟踪工具,用于检测C/C++程序中的内存泄露和其他内存错误。与dmalloc和memwatch相比,mtrace...
Linux 内核中的内存管理方式是非常复杂和细腻的,它需要深入了解 Linux 内核的实现原理和数据结构,以便更好地理解和应用 Linux 内核中的内存管理方式。 知识点: 1. Linux 内核中的内存管理方式 2. 伙伴系统算法...
- **内存对齐**:确保数据在内存中的位置符合特定边界,提高访问效率。 5. **进程内存管理**: - **堆和栈**:栈用于快速存取局部变量,堆用于动态分配大块内存。 - **共享内存**:多个进程可以共享同一块内存...
以上总结的知识点涵盖了Linux内存管理的核心概念和机制,从页面类型到内存区域的划分,再到页面的回收逻辑和内存管理规则,构成了Linux内核内存管理的基础。这些机制的设计和实现是Linux能够在现代计算机系统中高效...
### 查看Linux系统内存使用情况 #### 一、Free 命令详解 在Linux操作系统中,`free` 命令是一个非常重要的工具,用于查看系统的内存使用情况。...希望本文能够帮助您更好地掌握Linux内存管理的相关知识。
linux下c/c++ 实现cpu使用率查询,内存使用率查询,当个程序使用查询 主要应用/proc/stat /proc/meminfo /proc/pid/stat /proc/pid/status 等文件中的内容进行计算
本资源《嵌入式Linux内存与性能详解》详细阐述了这些关键领域,为理解嵌入式系统的内在机制提供了深入见解。 1. **嵌入式系统概述**:嵌入式系统通常具有特定功能,它们在硬件限制下运行,如处理能力、内存大小和...