概念:
虚拟内存(Virtual Memory):
首先需要强调的是虚拟内存不同于物理内存,虽然两者都包含内存字眼但是它们属于两个不同层面的概念。进程占用虚拟内存空间大并非意味着程序的物理内存也一定占用很大。
虚拟内存是操作系统内核为了对进程地址空间进行管理(process address space management)而精心设计的一个逻辑意义上的内存空间概念。我们程序中的指针其实都是这个虚拟内存空间中的地址。比如我们在写完一段C++程序之后都需要采用g++进行编译,这时候编译器采用的地址其实就是虚拟内存空间的地址。因为这时候程序还没有运行,何谈物理内存空间地址?凡是程序运行过程中可能需要用到的指令或者数据都必须在虚拟内存空间中。既然说虚拟内存是一个逻辑意义上(假象的)的内存空间,为了能够让程序在物理机器上运行,那么必须有一套机制可以让这些假象的虚拟内存空间映射到物理内存空间(实实在在的RAM内存条上的空间)。这其实就是操作系统中页映射表(page table)所做的事情了。内核会为系统中每一个进程维护一份相互独立的页映射表。
虚拟内存是一个假象的内存空间,在程序运行过程中虚拟内存空间中需要被访问的部分会被映射到物理内存空间中。虚拟内存空间大只能表示程序运行过程中可访问的空间比较大,不代表物理内存空间占用也大。
驻留内存(Resident Memory):
驻留内存,顾名思义是指那些被映射到进程虚拟内存空间的物理内存。进程的驻留内存就是进程实实在在占用的物理内存。一般我们所讲的进程占用了多少内存,其实就是说的占用了多少驻留内存而不是多少虚拟内存。因为虚拟内存大并不意味着占用的物理内存大。
查看内存命令:
free -m
一、在Linux下查看内存我们一般用free命令:

total:总计物理内存的大小。
used:已使用多大。
free:可用有多少。
Shared:多个进程共享的内存总额。
Buffers/cached:磁盘缓存的大小。
第三行(-/+ buffers/cached):
used:已使用多大。
free:可用有多少。
第二行(mem)的used/free与第三行(-/+ buffers/cache) used/free的区别:
从使用的角度来看,第一行是从OS的角度来看,因为对于OS,buffers/cached 都是属于被使用,所以他的可用内存是9546708KB,已用内存是6787132KB,其中包括,内核(OS)使用+Application(X, oracle,etc)使用的+buffers+cached.
第三行所指的是从应用程序角度来看,对于应用程序来说,buffers/cached 是等于可用的,因为buffer/cached是为了提高文件读取的性能,当应用程序需在用到内存的时候,buffer/cached会很快地被回收。
所以从应用程序的角度来说,可用内存 = 系统free memory + buffers + cached。
如上例:13708076=9480876+221112+4006088
/proc/meminfo 机器的内存使用信息
/proc/pid/maps pid为进程号,显示当前进程所占用的虚拟地址。
/proc/pid/statm 进程所占用的内存
/proc/pid/status 某个进程占用内存信息,还包括进程IDs、信号等信息
/proc/pid/smaps 查看进程的虚拟内存空间的分布情况
status 文件
二、Linux中查看某个进程占用内存的情况,执行如下命令即可,将其中的[pid]替换成相应进程的PID号:
cat /proc/[pid]/status
说明
/proc/pid/status 中所保存的信息除了内存信息,还包括进程IDs、信号等信息,此处暂时只介绍内存相关的信息。
| 字段 | 说明 |
|---|---|
| VmPeak | 进程所使用的虚拟内存的峰值 |
| VmSize | 进程当前使用的虚拟内存的大小 |
| VmLck | 已经锁住的物理内存的大小(锁住的物理内存不能交换到硬盘) |
| VmHWM | 进程所使用的物理内存的峰值 |
| VmRSS | 进程当前使用的物理内存的大小 |
| VmData | 进程占用的数据段大小 |
| VmStk | 进程占用的栈大小 |
| VmExe | 进程占用的代码段大小(不包括库) |
| VmLib | 进程所加载的动态库所占用的内存大小(可能与其它进程共享) |
| VmPTE | 进程占用的页表大小(交换表项数量) |
| VmSwap | 进程所使用的交换区的大小 |
smaps文件
三、查看进程的虚拟内存空间的分布情况,命令是:cat /proc/进程的pid/smaps
如果我想知道如下问题:
比如heap占用了多少空间、文件映射(mmap)占用了多少空间、stack占用了多少空间?
进程是否有被交换到swap空间的内存,如果有,被交换出去的大小?
mmap方式打开的数据文件有多少页在内存中是脏页(dirty page)没有被写回到磁盘的?
mmap方式打开的数据文件当前有多少页面已经在内存中,有多少页面还在磁盘中没有加载到page cahe中?
等等
linux通过proc文件系统为每个进程都提供了一个smaps文件,通过分析该文件我们就可以一一回答以上提出的问题。
在smaps文件中,每一条记录表示进程虚拟内存空间中一块连续的区域。其中第一行从左到右依次表示地址范围、权限标识、映射文件偏移、设备号、inode、文件路径。详细解释可以参见understanding-linux-proc-id-maps。
接下来8个字段的含义分别如下:
Size:表示该映射区域在虚拟内存空间中的大小。
Rss:表示该映射区域当前在物理内存中占用了多少空间。
Shared_Clean:和其他进程共享的未被改写的page的大小。
Shared_Dirty: 和其他进程共享的被改写的page的大小。
Private_Clean:未被改写的私有页面的大小。
Swap:表示非mmap内存(也叫anonymous memory,比如malloc动态分配出来的内存)由于物理内存不足被swap到交换空间的大小。
Pss:该虚拟内存区域平摊计算后使用的物理内存大小(有些内存会和其他进程共享,例如mmap进来的)。比如该区域所映射的物理内存部分同时也被另一个进程映射了,且该部分物理内存的大小为1000KB,那么该进程分摊其中一半的内存,即Pss=500KB。
statm文件
四、查看进程所占用的内存 命令:cat /proc/self/statm

输出解释 第一列 size:任务虚拟地址空间大小 第二列 Resident:正在使用的物理内存大小 第三列 Shared:共享页数 第四列 Trs:程序所拥有的可执行虚拟内存大小 第五列 Lrs:被映像倒任务的虚拟内存空间的库的大小 第六列 Drs:程序数据段和用户态的栈的大小 第七列 dt:脏页数量
其他:
用/proc文件系统查看进程的内存使用情况
/proc目录Linux 内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构、改变内核设置的机制。proc文件系统是一个伪文件系统
/proc/vmstat 虚拟内存统计信息
/proc/vmcore 内核panic时的内存映像
/proc/diskstats 取得磁盘信息
/proc/schedstat kernel调度器的统计信息
/proc/zoneinfo 显示内存空间的统计信息,对分析虚拟内存行为很有用
以下是/proc目录中进程N的信息
/proc/N pid为N的进程信息
/proc/N/cmdline 进程启动命令
/proc/N/cwd 链接到进程当前工作目录
/proc/N/environ 进程环境变量列表
/proc/N/exe 链接到进程的执行命令文件
/proc/N/fd 包含进程相关的所有的文件描述符
/proc/N/maps 与进程相关的内存映射信息
/proc/N/mem 指代进程持有的内存,不可读
/proc/N/root 链接到进程的根目录
/proc/N/stat 进程的状态
/proc/N/statm 进程使用的内存的状态
/proc/N/status 进程状态信息,比stat/statm更具可读性
/proc/self 链接到当前正在运行的进程
参考链接:
https://blog.youkuaiyun.com/qq_39584315/article/details/80311070
http://hutaow.com/blog/2014/08/28/display-process-memory-in-linux/
本文介绍了如何在Linux中查看进程的内存占用情况,包括虚拟内存、驻留内存的概念,以及`free -m`、`/proc/pid/status`、`/proc/pid/smaps`等命令的使用。通过`/proc`文件系统可以详细分析进程的内存分布,如堆、文件映射、堆栈等信息,并理解不同内存统计字段的含义。
3073

被折叠的 条评论
为什么被折叠?



