设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 创业者 数据 手机
当前位置: 首页 > 运营中心 > 网站设计 > 教程 > 正文

加深分析linux内存使用的情况详解

发布时间:2022-06-16 14:41 所属栏目:48 来源:互联网
导读:有朋友发现有台128的内存结果发现在使用时有点不对了,下面小编整理了一篇关于linux内存去哪儿了问题解决办法吧. 前两天一台128G内存的oracle主机发生故障触发kdump,最终由于var目录空间不足,导致kdump生成不完全,结合之前redhat给出的建议,crash设置的空间最
  有朋友发现有台128的内存结果发现在使用时有点不对了,下面小编整理了一篇关于linux内存去哪儿了问题解决办法吧.
 
  前两天一台128G内存的oracle主机发生故障触发kdump,最终由于var目录空间不足,导致kdump生成不完全,结合之前redhat给出的建议,crash设置的空间最好大于memory 空间,对此我们做了一个简单的计算,认为kdump主机生成的是运行在内存里的信息,虽然主机有128G的内存,不过通过top查看并计算后发现我实际上只使用7G多的大小,而使用free -m查看时已经使用了80G左右的内存,站在DBA的角度看的话,这部分内存提前分配给了sga,貌似也可以讲通,记得之前看过taobao褚霸写的一篇分析,这里再结合该文章算算.
 
  通过褚霸的Linux Used内存到底哪里去了?我们已经了解到内存主要消耗在三个方面:
 
  1.进程消耗
 
  2.slab消耗
 
  3.pagetable消耗
 
  由于不便于直接在现网oracle主机上进行操作,这里就以本blog的云主机为例进行测试.
 
  一、查看已用内存总量
 
  [root@91it ~]# free -m
               total       used       free     shared    buffers     cached
  Mem:           996        908         88          0        174        283
  -/+ buffers/cache:        450        546
  Swap:            0          0          0
  于已用内存和可用内存这已经是一个老生长谈的问题了,这里看到的信息如下.
 
  1、总内存996M,已用内存908M
 
  2、由于buffers + cached内存实际上也是可用内存,该内存也可以通过echo 3 > /proc/sys/vm/drop_caches 回收pagechae、dentries and inodes,所以实际上已经使用的内存是450M.
 
  注:1、关于内存的计算方法就不上图了,这点可以参考:http://www.redbooks.ibm.com/redpapers/pdfs/redp4285.pdf
 
  2、linux内存强制回收的方法具体可以参考:linux 下 强制回收内存.
 
  即然实际使用了450M内存,那这450M内存是如何分配的呢?
 
  二、RSS内存(Resident size)
 
  ps下命令下的RSS内存、top工具下的RES内存都是指的这一块内存,resident set size 也就是每个进程用了具体的多少页的内存,由于linux系统采用的是虚拟内存,进程的代码,库,堆和栈使用的内存都会消耗内存,但是申请出来的内存,只要没真正touch过,是不算的,因为没有真正为之分配物理页面,说白了也就是真正具有“数据页的物理内存”,我这里使用的是一段从python psutil 模块里演化出的一段代码进行计算的:
 
  [root@91it ~]# cat vms.py
  #!/usr/bin/python
  import os
  def get_vms(pid):
              with open("/proc/%s/statm" % pid, "rb") as f:
                  vms = f.readline().split()[1]
                  return int(vms)
  pids = [int(x) for x in os.listdir(b'/proc') if x.isdigit()]
  vmss = [get_vms(pid) for pid in pids]
  print sum(vmss) * 4
  [root@91it ~]# python vms.py
  386528
  注:1、/proc/PID/statm 第二列是RSS内存使用page页的多少,而在linux下默认使用的page页大小是4KB,所以我上面计算求和后,最后乘以4,而我最终计算出的结果就是386528KB.
 
  2、这里也可以通过/proc/PID/status里的vmRss项进行求和,因为该项直接给出的是KB值.
 
  [root@91it ~]# cat /proc/998/status
  Name:   mingetty
  State:  S (sleeping)
  Tgid:   998
  Pid:    998
  PPid:   1
  TracerPid:      0
  Uid:    0       0       0       0
  Gid:    0       0       0       0
  Utrace: 0
  FDSize: 64
  Groups:
  VmPeak:     4068 kB
  VmSize:     4064 kB
  VmLck:         0 kB
  VmHWM:       556 kB
  VmRSS:        76 kB
  ………………………………
  当然也可以使用shell 进行计算:
 
  $ cat RSS.sh
  #/bin/bash
  for PROC in `ls  /proc/|grep "^[0-9]"`
  do
    if [ -f /proc/$PROC/statm ]; then
        TEP=`cat /proc/$PROC/statm | awk '{print ($2)}'`
        RSS=`expr $RSS + $TEP`
    fi
  done
  RSS=`expr $RSS * 4`
  echo $RSS"KB"
  rss内存部分,具体可以查看man proc手册或kernl 页的介绍,以下是man proc 里的部分提取:
 
  /proc/[pid]/statm
  Provides information about memory usage, measured in pages. The
  columns are:
  size total program size
  (same as VmSize in /proc/[pid]/status)
  resident resident set size
  (same as VmRSS in /proc/[pid]/status)
  share shared pages (from shared mappings)
  text text (code)
  lib library (unused in Linux 2.6)
  data data + stack
  dt dirty pages (unused in Linux 2.6)
  二、slab内存
 
  slab内存的作用是内核为了高性能每个需要重复使用的对象都会有个池,这个slab池会cache大量常用的对象,所以会消耗大量的内存,具体可以运行slabtop命令查看.
 
  slab内存的消耗我们可以通过/proc/slabinfo文件算出,具脚本为:
 
  #  echo `cat /proc/slabinfo |awk 'BEGIN{sum=0;}{sum=sum+$3*$4;}END{print sum/1024/1024}'` MB
  74.7215 MB
  三、PageTables内存
 
  这部分内存我并没有细研究,这里就直接拉taobao上各位大牛的说法用吧:“struct page也有一定的大小(每个页一个,64bytes),如果是2.6.32的话,每个页还有一个page_cgroup(32bytes),也就是说内存大小的2.3%(96/4096)会被内核固定使用,struct page是系统boot的时候就会根据内存大小算出来分配出去的,18内核是1.56%左右,32内核由于cgroup的原因会在2.3%.”
 
  而具体消耗可以通过/proc/meminfo里的pagetables项获取,脚本如下:
 
  # echo `grep PageTables /proc/meminfo | awk '{print $2}'` KB
  4476 KB
  系统的硬开销占比并不多.
 
  四、其他情况
 
  在第四步算算总帐中,我们看出 rrs内存 + slab内存 + pagetables内存 > 实际已用内存,但该情况并非是绝对的,也有例外,在我上面提到的oracle 使用场景下,事先分配了70g左右的oracle sga 空间(即内存空间),而三者相加要远远小于实际使用的物理内存,这又要怎么解释呢?再去除cache和buffer的空间也要远远小于实际使用的内存.
 
  [root@irora04s ~]# free -m
               total       used       free     shared    buffers     cached
  Mem:        129023     100024      28999          0        885      12595
  -/+ buffers/cache:      86543      42480
  Swap:        24575          0      24575
  [root@irora04s ~]# sh /tmp/mem.sh
  4339696KB, 66056KB, 745.805MB
  rss+pagetable+slabinfo=5046.805MB
               total       used       free     shared    buffers     cached
  Mem:        129023     100096      28926          0        885      12597
  -/+ buffers/cache:      86614      42409
  Swap:        24575          0      24575
  我个人的理解是事先分配的这部分sga内存,大部分是空page页,在未使用时虽然空间被占用了,但该内存地址内并不存在数据,所以一旦该机触发kdump 时,crash 的内存空间占用的磁盘空间 接近于rss+pagetable+slabinfo,小于rss+pagetable+slabinfo+buffers+cached.
 
  最后这里同样推荐有时间看下nmon的源码,因为从nmon的内存统计信息来看,更便于理解内存的几个去向.
 
 

(编辑:ASP站长网)

    网友评论
    推荐文章
      热点阅读