学习查看 linux 关于进程的文件信息 cat /proc/968/status
(1) 在 Linux 系统中,/proc 文件系统是一个伪文件系统,提供了一个接口来访问内核数据结构。/proc/[pid]/status 文件包含了关于特定进程的状态信息。当你运行 cat /proc/968/status 时,它会输出与进程 ID 为 968 的进程相关的状态信息。
用大量篇幅介绍与记录 RUID 和 EUID,我们用 test 用户启动 top 进程 , 如下 谢谢这位老师:
终端1)
su - test
top
查看该进程的 EUID 和 RUID , 如下 :
终端2)
cat /proc/pgrep top|grep -v grep
/status
前面略
Uid: 1002 1002 1002 1002
Gid: 1003 1003 1003 1003
后面略
注:这里我们看到进程的 RUID 和 EUID 都变成了 1002.
我们将程序 top 加上 setuid 权限,如下:
chmod +s /usr/bin/top
重新运行 top 程序,并查看它的 RUID 和 EUID , 如下:
cat /proc/pgrep top|grep -v grep
/status
前面略
Uid: 1002 0 0 0
Gid: 1003 0 0 0
后面略
注:我们看到 RUID 还是 1002,说明程序是由 test 用户(UID=1002)启动的,而程序设定了 setuid , 那么在程序运行时是用程序的 owner 权限来运行程序,而不是启动的用户权限.
由于 top 的 owner 是 root ,那么它的 EUID 是 0 .
(2) 继续解释 Groups 参数:
Groups : 0
解释:
这里的 groups 表示启动这个进程的用户所在的组.
我们当前的用户 test ,现在在两个组 (1000 , 2000) 里面 , 如下 :
id
uid=1002(test) gid=1002(nagcmd) groups=1000(chenkuo), 1002(nagcmd)
用 test 用户启动 top 程序,并查看它的 groups , 如下:
终端1
top
终端2
cat /proc/pgrep top|grep -v grep
/status
截取信息如下:
Groups: 1000 1002
(3)VmPeak: 36528 kB
解释:这里的 VmPeak 代表当前进程运行过程中占用内存的峰值 .
我们用下面的程序申请内存,然后释放内存,最后通 pause() 函数中止程序的运行,程序源码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int
main (int argc, char *argv[])
{
if (argc != 2) exit (0);
size_t mb = strtoul(argv[1],NULL,0);
size_t nbytes = mb * 0x100000;
char * ptr = (char *) malloc(nbytes);
if (ptr == NULL){
perror("malloc");
exit (EXIT_FAILURE);
}
printf("allocated %d mb\n", mb);
free(ptr);
pause();
return 0;
}
++编译 :gcc callmem.c -o callmem
./callmem 10
allocated 10 mb
终端2
我们打开status文件,查看 VmPeak 值,如下:
cat /proc/pgrep callmem | grep -v grep
/status
Groups: 1000 1002
VmPeak: 11852 kB
VmSize: 1608 kB
VmLck: 0 kB
注:我们看到程序申请了 10240kb(10MB) 的内存 , VmPeak的值为 11852 kb , 为什么不是 10MB 呢 , 因为除了我们申请的内存外 , 程序还会为加载动态链接库而占用内存.
(4)VmLck: 0 kB
解释 : VmLck 代表进程已经锁住的物理内存的大小 。 锁住的物理内存不能交换到硬盘 .
我们用下面的程序进行测试,如下:
#include <stdio.h>
#include <sys/mman.h>
int main(int argc, char* argv[])
{
char array[2048];
if (mlock((const void *)array, sizeof(array)) == -1) {
perror("mlock: ");
return -1;
}
printf("success to lock stack mem at: %p, len=%zd\n", array, sizeof(array));
sleep(60);
if (munlock((const void *)array, sizeof(array)) == -1) {
perror("munlock: ");
return -1;
}
printf("success to unlock stack mem at: %p, len=%zd\n", array, sizeof(array));
return 0;
}
++ 编译后运行:
gcc memlock.c -o memlock
我们这里将 2048 个字节的数组地址空间锁定到了物理内存中.
接下来我们看下 Vmlck 值的变化,如下:
cat /proc/pgrep memlock | grep -v grep
/status
VmPeak: 1624 kB
VmSize: 1608 kB
VmLck: 4 kB
VmHWM: 356 kB
我们看到 Vmlck 的值为 4Kb , 这是因为分配的最少单位是 4KB , 以后每次递增都是 4KB 的整数倍.
(5)VmHWM: 1432 kB
VmRSS: 1420 kB
解释:
VmHWM是程序得到分配到物理内存的峰值.
VmRSS是程序现在使用的物理内存.
我们用下面的程序进行测试 , 如下 :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int
main (int argc, char *argv[])
{
if (argc != 2)
exit (0);
size_t mb = strtoul(argv[1],NULL,0);
size_t nbytes = mb * 0x100000;
char *ptr = (char *) malloc(nbytes);
if (ptr == NULL){
perror("malloc");
exit (EXIT_FAILURE);
}
size_t i;
const size_t stride = sysconf(_SC_PAGE_SIZE);
for (i = 0;i < nbytes; i+= stride) {
ptr[i] = 0;
}
printf("allocated %d mb\n", mb);
pause();
return 0;
}
编译:
gcc callmem.c -o test
注意这个程序在每页都修改一个字节的数据,导致系统必须为它分配占用物理内存.
首先我们查看当前的内存,如下 :
free -m
total used free shared buffers cached
Mem: 503 18 484 0 0 5
-/+ buffers/cache: 12 490
Swap: 7632 7 7624
我们看到当前有 490MB 的空闲物理内存.
运行 callmem 分配 450MB 的物理内存,如下:
./test 450&
[1] 2402
allocated 450 mb
我们查看进程的 VmHWM 和 VmRSS ,如下 :
cat /proc/`pgrep test`/status
#略
VmHWM: 461208 kB
VmRSS: 461208 kB
#略
我们看到此时VmHWM和VmRSS是一样的,表示占用了460MB左右的物理内存(因为它会用到动态链接库等).
下面我们查看当前的内存使用情况,如下:
free -m
total used free shared buffers cached
Mem: 503 470 33 0 0 6
-/+ buffers/cache: 463 40
Swap: 7632 7 7625
我们看到还有40MB空闲物理内存.
我们下面再申请100MB的内存,此时系统会通过物理内存和SWAP的置换操作,把第1次运行的test进程所占用的物理内存置换到SWAP,把空出来的物理内存分配给第2次运行的程序,如下:
mv test test1
./test1 100&
[1] 2419
allocated 100 mb
再次查看test进程所占用的物理内存,如下:
cat /proc/`pgrep test`/status
#略
VmHWM: 461208 kB
VmRSS: 386704 kB
#略
最后我们看到VmHWM没有变化,因为它表示的是该进程所占用物理内存的峰值,不会因为把内存置换到SWAP,而做改变.
而VmRSS则由461208KB变成了386704KB,说明它占用的物理内存因为置换所以减少.
(6) 给出整理的图, 这位大师也总结与整理的很好,谢谢,看这一篇 , 这一篇也非常好,谢谢:
++ 分析这个 968 进程:
(7)
(8)
(9) linux 的 speculation store bypass状态 :
(10) NUMA 系统:
(11)
谢谢