在Linux上通过top看到的RES和SHR的值很高,表示进程占用的内存很多吗?会有什么问题吗?
要搞清楚这个问题,首先从top输出开始研究:
top命令的输出中VIRT RES SHR这三列的意思我就不多解释了,man top 一下就明白了。
VIRT 是进程使用的总的虚拟内存大小。
RES 是常驻内存的大小(不能SWAP)。
SHR 是共享内存的大小(包括共享库等)。
然后看一下这几个值分别是从哪里来的?看了一下top命令的源代码,在m_linux.c中有这几个值的来源,简单说就是,
这些值都是从/proc/$pid 下面读出来的:
VIRT 是 /proc/$pid/stat 中的第23个数字。
RES 是/proc/$pid/stat 中的第24个数字,但是要注意,这个是用页来表示的,所以需要成字节。
SHR 是 /proc/$pid/statm 中的第三个数字,这个也是用页表示的,需要转换。
总的虚拟内存大小不用管它,这里主要关注RES 和 SHR。
查看linux内核代码可知
RES的值获取方式如下:
mm ? get_mm_rss(mm) : 0
而get_mm_rss的定义如下:
411 #define get_mm_rss(mm) \
412 (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss))
412 (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss))
而get_mm_counter也是一个宏,它获取了进程的内存结构体mm_struct中变量 _file_rss 和_anon_rss 成员。
SHR的获取代码如下:
*shared = get_mm_counter(mm, file_rss);
由此可见:
RES = mm_struct->_file_rss + mm_struct->_anon_rss
SHR = mm_struct->file_rss
那么,file_rss 和anon_rss是怎么计算出来的?它们代表的意思又是什么?要彻底搞清楚这两个东西,直接从代码上解释比较麻烦,比较不容易说清楚。
但是我们可以换个地方去寻找答案。
我们发现,在/proc/$pid 下面还有其他的一些文件,那么这些文件又是什么意思呢?有没有用的上的呢?其实是有的。
/proc/$pid/maps 这个文件描述了当前映射到进程的内存和它们的访问权限
/proc/$pid/smaps 这个文件是对/proc/$pid/maps更详细的描述,包括了每个映射内存的大小和使用情况 (具体参见文档 kernel/Documentation/filesystems/proc.txt)
在我的机器上将进程ID为50893,RES=2.3G的进程的 statm 和 smaps 保存到文件:
cat /proc/50893/statm > statm
cat /proc/50893/smaps > smaps
[ocsrun@OCSPROXY1 lqb]$ cat statm
1467525 602414 601853 29 0 559 0
这里重点关注第二个数字,这个数是什么意思以及怎么取到的后面会说。
[ocsrun@OCSPROXY1 lqb]$ grep Rss smaps |awk 'BEGIN {sum = 0;} {sum += $2} END{print sum}'
2409656
然后发现:602414 × 4K = 2409656K 与smaps中所有的Rss的和相等。
而2409656 / 1024 / 1024 = 2.298 = 2.3G 这不就是RES的大小吗?
现在来说statm 中的第二个数,这个数就是 file_rss + anon_rss,代码我就不贴了,参看/kernel/fs/proc/array.c 和 /kernel/fs/proc/task_mmu.c
而smaps中所有的Rss,是遍历进程所有的虚拟映射链表,一个一个累加出来的。以下是相关结构体的片段。
202 struct mm_struct {
203 struct vm_area_struct * mmap; /* list of VMAs */
134 struct vm_area_struct {
135 struct mm_struct * vm_mm; /* The address space we belong to. */
136 unsigned long vm_start; /* Our start address within vm_mm. */
137 unsigned long vm_end; /* The first byte after our end address
138 within vm_mm. */
至此我们知道file_rss + anon_rss 就是进程所有映射的页面的大小,注意这里说的都是虚拟地址空间,而不是物理内存(当然也包括了一部分的物理内存)。
前面那个关于file_rss 和 anon_rss的问题算是基本上搞清楚了,但是为什么有的进程的映射页面会突然变得很大呢?
为了搞清楚这个问题,我们仔细查看一下smaps文件:
仔细查看后发现,smaps里面包括了所有映射的动态库,heap,stack等等。当然也包括了共享内存。
共享内存是以下面的方式而存在的:
7f43d5445000-7f4515445000 rw-s 00000000 00:04 8749063 /SYSV00c9b457 (deleted)
Size: 5242880 kB
Rss: 2098384 kB
Pss: 1052946 kB
Shared_Clean: 541256 kB
Shared_Dirty: 1548472 kB
Private_Clean: 7656 kB
Private_Dirty: 1000 kB
Referenced: 2098364 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
而普通共享库是这样的:
7f452c11d000-7f452c4c9000 r-xp 00000000 08:09 8172 /home/ocsrun/xerces-c/xerces-c-3.0.0/lib/libxerces-c-3.0.so
Size: 3760 kB
Rss: 1336 kB
Pss: 93 kB
Shared_Clean: 1336 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 0 kB
Referenced: 1336 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
将上面共享内存的行移下来:
7f43d5445000-7f4515445000 rw-s 00000000 00:04 8749063 /SYSV00c9b457(deleted)
该行的意思如下:第一列是(虚拟)地址映射空间,第二列是访问权限,第三列是偏移量,第四列是设备号,以主设备号:次设备号的方式显示,第五列是inode,最后一列是路径。
这里为什么是deleted呢?因为对于共享内存来说,根本不存在实际的文件跟它对应。
运行ipcs输出如下(部分输出):
[ocsrun@OCSPROXY1 ~]$ ipcs
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00c9b455 8683525 ocsrun 660 103415808 5
0x00c9b456 8716294 ocsrun 660 279150592 5
0x00c9b457 8749063 ocsrun 660 5368709120 5
0x00c9b45f 8781832 ocsrun 660 103415808 8
可以看到,在smaps中共享内存的inode是8749063,也就是ipcs显示的shmid,而key就是文件路径的后面一段。
如上面所示,共享内存的映射有一个大于2G的,所以加上另外两块共享内存的映射,总的RES有2.3G也就不奇怪了。
而关于共享内存的分配,多说两句:sys v shared memory实现,shmget基本就是在ramfs上写一个名字是SYSV<shm_key>的文件(这里是/SYSV00c9457),
然后该文件的inode号是内核ipc核心数据结构的唯一id号,之后shmat基本就是mmap这个文件的过程,也就是说shmget返回的shmid其实就是用于存储内容的文件的inode编号。
然后该文件的inode号是内核ipc核心数据结构的唯一id号,之后shmat基本就是mmap这个文件的过程,也就是说shmget返回的shmid其实就是用于存储内容的文件的inode编号。
所以:Linux上top输出中RES和SHR的值比较高是没有关系的,因为可能大部分都是共享内存。top和ps等的输出中关于内存占用的部分都包括了共享内存/共享库等占用的虚拟内存空间。
相关推荐
查看 LINUX 进程内存占用情况 Linux 操作系统中查看进程内存占用情况是系统管理员和开发人员日常任务中非常重要的一部分。通过查看进程内存占用情况,可以了解系统中进程的资源占用状况,故障排查和性能优化。下面...
"查看LINUX进程内存占用情况" ...top、pmap 和 ps 命令都是查看 Linux 进程内存占用情况的常用命令,每个命令都有其特点和优势,选择合适的命令可以帮助开发者和系统管理员更好地管理和优化系统性能。
4. NI:nice值,表示进程的调度优先级,正数表示较低优先级,负数表示较高优先级。 5. VIRT:进程占用的虚拟内存总量,包括共享库、堆栈和交换空间。 6. RES:进程占用的物理内存,不包括交换空间。 7. SHR:进程...
在给出的示例中,可以看到`top`命令默认显示的信息包括:PID(进程ID)、USER(用户)、PR(优先级)、NI(Nice值)、VIRT(虚拟内存大小)、RES(物理内存占用)、SHR(共享内存)、S(状态)、%CPU(CPU使用率)、...
5. **虚拟内存与物理内存**:VIRT和RES分别表示进程的虚拟内存和物理内存占用,SHR表示共享内存。 通过熟练掌握`top`命令,系统管理员可以有效地监控和调整系统的资源分配,优化系统性能,解决内存泄漏、CPU过高或...
Linux top 命令是 Linux 下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于 Windows 的任务管理器。下面详细介绍它的使用方法。 认识 top 的显示结果 ------------------- top 命令的显示...
包括PID(进程ID)、USER(进程所有者)、PR(优先级)、NI(Nice值)、VIRT(虚拟内存占用)、RES(物理内存占用)、SHR(共享内存占用)、%CPU(CPU使用率)、%MEM(内存使用率)、TIME+(CPU时间累计)和COMMAND...
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器 内容解释: PID:进程的ID USER:进程所有者 PR:进程的优先级别,越小越优先被执行 ...
首先,`top`命令是Linux中用于实时查看系统性能的工具,它能显示各个进程的资源占用情况,包括CPU使用率、内存占用等。当运行`top`命令后,系统会进入全屏交互模式,可以按`q`键退出。在`top`命令的输出中,你可以...
例如,`PID`是进程ID,`PR`和`NI`表示进程的优先级,`%CPU`是进程使用的CPU时间百分比,`%MEM`是进程使用的物理内存百分比,`VIRT`是进程的虚拟内存总量,`RES`是进程实际使用的物理内存,`SHR`是共享内存,`COMMAND...
`top`命令会以全屏交互模式显示系统信息,包括每个进程的CPU使用率、内存占用情况等。要退出`top`,只需按下`q`键。在`top`界面中,你可以看到如下信息: 1. **PID**: 进程的唯一标识符。 2. **USER**: 进程的所有...
- **ni**:nice值,表示进程的优先级,负值意味着更高的优先级。 - **id**:空闲CPU时间,表示CPU没有执行任何进程的时间百分比。 - **wa**:等待I/O操作的CPU时间百分比。 - **hi**和**si**:硬件中断和软件...
除了查看默认的输出外,`top`命令还支持很多实用的功能,比如排序、过滤、定时刷新等。 - **按内存使用量排序**: 按`M`键可以按照内存使用量对进程进行排序。 - **按CPU使用率排序**: 按`P`键可以按照CPU使用率对...
负载值越高,表示有更多的进程在等待处理。 - **任务队列信息**:展示系统中进程的总体情况,包括总的进程数量、正在运行的进程数、睡眠状态的进程数等。 - **CPU使用情况**:展示CPU的使用情况,包括用户空间、内核...
`top` 命令是 Linux 系统中非常重要的实时监控工具之一,主要用于查看和监控系统资源使用情况,特别是 CPU 和内存的使用情况。虽然大多数程序员都熟悉 `top` 命令的基本使用,但在深入理解和高效利用该命令方面仍...
`top` 命令是Linux操作系统中一个强大的实时系统监视工具,用于查看系统整体的性能状态,包括CPU、内存使用情况以及正在运行的进程等信息。它是一个动态的视图,可以实时更新显示的数据,使得管理员能够及时了解系统...
`top`命令是Linux系统中一个非常实用且强大的工具,用于实时显示系统中各个进程的资源占用状况。它提供了CPU使用率、内存使用情况以及系统运行时间等信息,是系统管理员进行性能监控的重要手段之一。 在给定的示例...
`top` 命令是Linux操作系统中一个非常实用且强大的工具,它可以实时地展示系统中各个进程的资源占用情况,包括CPU使用率、内存使用量等关键指标。这与Windows系统中的任务管理器功能类似,但在Linux环境下提供了更...