jackiedai

计算linux使用了多少内存

一,系统有多少空闲内存?

 

关键一点,要在除去LINUX使用的文件系统"Cached"和磁盘buffers后的结果。

什么是文件系统"cached"和磁盘buffers? 请见free 输出中的cachedbuffers

 

# free -m

total       used       free     shared    buffers     cached

Mem:           700       688         12          0        130        381

-/+ buffers/cache:        176        523

Swap:         1961         20       1940

 

上面这个176实际上是 688-130-381的结果  177 M。(约等于176,因为从km做了换算)

 

验证:

运行清空文件系统"cached"和磁盘buffer的命令

 

# echo 3 > /proc/sys/vm/drop_caches

就会看到

 

# free -m

             total       used       free     shared    buffers     cached

Mem:           700         48        651          0          0          8

-/+ buffers/cache:         40        660

Swap:         1961          7       1953

 

发现used为 40M, buffers为0,cached为8了。不知道为什么8M去不掉,关系不大吧,只有8M

这个严重建议看一下这篇:http://km.oa.com/group/SA/article_view/57194  其实这段就是抄这一篇的。

 

 

如果没有共享内存文章到这里就结束,但问题是还有共享内存。

 

二,共享内存存放在哪里?

答:SysV Shm存放在cached

如果查一下内核文档源码啥的,应该也能查出来;不过不会查。这次不讲理论,测试一下,眼见为实。

 

#1,找一个空的环境,清空文件系统"cached"和磁盘buffers,能看到系统used内存为40M

# echo 3 > /proc/sys/vm/drop_caches

# free -m

             total       used       free     shared    buffers     cached

Mem:           700         48       651          0          0          8

-/+ buffers/cache:         40        660

Swap:         1961          7       1953

 

#3 domem 是一个测试程序:

申请1G 共享内存,memset 100M内容为1sleep 1秒,把它的/proc/pid/smaps中关于共享内存的那一段打印出来

大概的源码是

        shmid = shmget(ftok(argv[0], 1), 1024ul *1024*1024*1 , IPC_CREAT|0666);

        printf("shmid: %d\n", shmid);

        mem = shmat(shmid, NULL, 0);

        memset (mem, \'1\', 1024*1024*100*1);

        sleep (1);

        printf("PID:%d\n", getpid());

        sprintf(sysbuf, "grep -A 6 SYSV  /proc/%d/smaps", getpid());

        system(sysbuf);

 

# ./domem sysv

# Command: sysv

shmid: 6520836

PID:5720

77de2000-b7de2000 rw-s 00000000 00:07 6520836    /SYSVffffffff (deleted)

Size:           1048576 kB

Rss:             102400 kB

Shared_Clean:         0 kB

Shared_Dirty:         0 kB

Private_Clean:        0 kB

Private_Dirty:   102400 kB

 

#4 看到,现在cached已经上涨到110M了,大约加了100M,不会是巧合吧

# free -m

             total       used       free     shared    buffers     cached

Mem:           700        150        549          0          0        110

-/+ buffers/cache:         39        660

Swap:         1961          7       1953

 

#5,清掉缓存,看到cached还有109M,清不掉了,还真是和刚才的100M SHM有关系

# echo 3 > /proc/sys/vm/drop_caches

# free -m

            total       used       free     shared    buffers     cached

Mem:           700        149        551          0          0        109

-/+ buffers/cache:         39        660

Swap:         1961          7       1953

 

#6,杀掉domem进程,再清io缓存,还是清不掉

# killall -9 domem

[1]+  Killed                  ./domem sysv

# free -m

             total       used       free     shared    buffers     cached

Mem:           700        150        549          0          0        111

-/+ buffers/cache:         39       660

Swap:         1961          7       1953

# echo 3 > /proc/sys/vm/drop_caches

# free -m

             total       used       free     shared    buffers     cached

Mem:           700        148        551          0          0        109

-/+ buffers/cache:         39        661

Swap:         1961          7       1953

 

#7 删除共享内存,再看,cached的值下来了,减少了约100M 

# ipcrm -m 6029316

# free -m

             total       used       free     shared    buffers     cached

Mem:           700         50        650          0          0         10

-/+ buffers/cache:         38        661

Swap:         1961          7       1953

 

#8  试一下posix shm,发现posix shm也是放在cached memory中的。

domem也支持posix shm的,大家有兴趣试一下,我就不写了。

./domem posix  posixfile 10

Domem.c在本文最后有下载连接。

 

三,共享内存的申请大小和已分配大小?

smaps文件中,有一些带有/SYSV开头的文件,就是共享内存了;当然,rw-s标志中的s才是关键。在下面这段中:

77de2000-b7de2000 rw-s 00000000 00:07 6520836    /SYSVffffffff (deleted)

Size:           1048576 kB

Rss:             102400 kB

Shared_Clean:         0 kB

Shared_Dirty:         0 kB

Private_Clean:        0 kB

Private_Dirty:   102400 kB

 

看到:Size是它申请的共享内存的大小,Rss是已分配到物理内存的量。

再跑一个./domem sysv

# PID:5833

77e11000-b7e11000 rw-s 00000000 00:07 6520836    /SYSVffffffff (deleted)

Size:           1048576 kB

Rss:             102400 kB

Shared_Clean:         0 kB

Shared_Dirty:    102400 kB

Private_Clean:        0 kB

Private_Dirty:        0 kB

看到:Rss没有变,但Private_Dirty变为0了,而Shared_Dirty变为100M了。

 

还看到:

内核会建一个临时文件/SYSVffffffff (deleted)  ,以它的inodeshmid

这里隐约能感觉到:共享内存和文件是相对应的,被内核算到cached还是比较合适。

在上面例子中, 6520836shmid,本来它应该是/SYSVffffffff的inode的。

 

四:计算 linux使用内存 的公式是?

 

free中去除cached/buffers后的used   + 已使用共享内存的Rss总和。

 

如果不那么精确,只查申请的SHMSIZE,又是Sysv SHM的话,可以用下面这串命令算,

# ipcs -m | awk \'{s+=$5} END {print s/1024/1024, "M"}\'

1026.76 M

 

如果是posix shm的话,那可能还得去遍历所有的smaps文件,grep一下第2个字段的最后一个字符为s(SHARE)的行,查一下它的Size

 

或者,光查ipcsSize都可能是不靠谱的,天知道开发同事们是怎么定义这个Size的;

光查Rss也不对,万一系统跑着跑着就把申请的内存用光了。所以说运维要和研发同事多沟通。

 

 

五,公司tnm网管系统上哪个内存性能指标是准确的?

 

用TNM系统查数据的同学看一下吧,不用的就忽略, 下面这个表是agent关于内存项采集的说明。

应用程序使用内存

agent读取/proc/meminfo文件,(MemTotal – MemFree – Buffers – Cached)/1024得到应用程序使用内存数。

MEM使用量

agent读取/proc/meminfo文件,MemTotal – MemFree得到MEM使用量。

Private内存

通过/proc/<进程ID>/smaps文件计算出所有进程的private内存总和。

Virtual内存

通过/proc/<进程ID>/samps计算出所有进程的virtual内存总和。

Private+IPCS

所有进程的private内存+ipcs内存的总和。

MEM使用量:WINDOWS的有意义,LINUX的意义不大

应用程序使用内存数:没有共享内存的情况下,最准确

private内存使用:每个shmid只有1个进程使用时,最准确

private内存加共享内存占用:每个shmid 有2个进程使用时,最准确

virtual内存使用:不懂

 

注意:网管agent采集内存量的时候,去遍历smaps文件取private_dirty/private_clean累加;

而使用linuxthread的程序,每一个线程都会有一个进程号,导致采集结果为线程数量倍数这么大。

不少老的mysqld就是使用这种线程库的。

 

六,SWAP?

 

想知道SWAP量多少时,我们可以接受?

想了很久没有想清楚。

mysqld由于oom killer被杀掉,就没有充分考虑sysv shm的情况!另外,文件系统的cache和磁盘的buffer,我之前就以为只有一个文件系统的cache!

附:http://sa.ied.com/download/domem.c 

分类:

技术点:

相关文章:

  • 2021-12-18
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-01-22
  • 2021-12-23
猜你喜欢
  • 2022-01-11
  • 2022-12-23
  • 2022-12-23
  • 2021-08-21
  • 2022-12-23
相关资源
相似解决方案