背景: CentOS 6.6 运行elasticsearch 3实例的机器内存报警。 通过top查看内存占小
# top Tasks: 394 total, 1 running, 393 sleeping, 0 stopped, 0 zombie Cpu(s): 1.0%us, 0.6%sy, 0.0%ni, 98.3%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 132119032k total, 118262316k used, 13856716k free, 383500k buffers Swap: 32767996k total, 0k used, 32767996k free, 7681488k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 46499 work 20 0 24.7g 10g 272m S 4.6 8.5 44561:27 java 60273 work 20 0 24.7g 2.1g 133m S 12.3 1.7 18:47.64 java 46228 work 20 0 23.7g 2.0g 15m S 0.7 1.6 5109:26 java 41782 work 20 0 5119m 582m 11m S 6.6 0.5 31402:18 java
# free -g total used free shared buffers cached Mem: 129022 115487 13535 1 374 7494 -/+ buffers/cache: 107618 21404 Swap: 31999 0 31999
内存到哪去了呢,下面我们来分析一下
1. 查看meminfo , 发现系统slab分配器占用了将近50G的内存
# cat /proc/meminfo MemTotal: 132119032 kB MemFree: 13829572 kB Buffers: 383500 kB Cached: 7704224 kB SwapCached: 0 kB Active: 17869672 kB Inactive: 6046628 kB Active(anon): 13601772 kB Inactive(anon): 2228420 kB Active(file): 4267900 kB Inactive(file): 3818208 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 32767996 kB SwapFree: 32767996 kB Dirty: 24796 kB Writeback: 0 kB AnonPages: 15828604 kB Mapped: 432376 kB Shmem: 1612 kB Slab: 93501144 kB SReclaimable: 93428284 kB SUnreclaim: 72860 kB KernelStack: 13296 kB PageTables: 41920 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 98827512 kB Committed_AS: 35260328 kB VmallocTotal: 34359738367 kB VmallocUsed: 505700 kB VmallocChunk: 34291725016 kB HardwareCorrupted: 0 kB AnonHugePages: 2048 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 7852 kB DirectMap2M: 3102720 kB DirectMap1G: 131072000 kB
2. 什么是slab
slab是Linux操作系统的一种内存分配机制. 其工作是针对一些经常分配并释放的对象,如进程描述符等,这些对象的大小一般比较小,如果直接采用伙伴系统来进行分配和释放,不仅会造成大量的内碎片,而且处理速度也太慢。而slab分配器是基于对象进行管理的,相同类型的对象归为一类(如进程描述符就是一类),每当要申请这样一个对象,slab分配器就从一个slab列表中分配一个这样大小的单元出去,而当要释放时,将其重新保存在该列表中,而不是直接返回给伙伴系统,从而避免这些内碎片。slab分配器并不丢弃已分配的对象,而是释放并把它们保存在内存中。当以后又要请求新的对象时,就可以从内存直接获取而不用重复初始化。
3. 查看slab缓存信息(可用slabtop命令查看)
# cat /proc/slabinfo |awk ‘{if($3*$4/1024/1024 > 100){print $1,$3*$4/1024/1024} }‘ dentry 84990.7 buffer_head 461.191
4. strace 进程号
strace -fp 60273 [pid 8449] write(573, "?\327l\27\23Lucene46SegmentInfo\0\0\0\1\0034.9"..., 289) = 289 [pid 8449] write(573, "\0\0\0\0(\352\330\274", 8) = 8 [pid 8449] close(573) = 0 [pid 8449] open("/opt/crm-es/node2/data/crmdev_tjidc/nodes/0/indices/0323_1926/2/index/_bb1zl.cfs", O_RDONLY) = 573 [pid 8449] fstat(573, {st_mode=S_IFREG|0664, st_size=17594, ...}) = 0 [pid 8449] pread(573, "?\327l\27\26CompoundFileWriterData\0\0\0\1?"..., 1024, 0) = 1024 [pid 8449] open("/opt/soft/crm-es/node2/data/crmdev_tjidc/nodes/0/indices/0323_1926/2/index/_bb1zl.cfe", O_RDONLY) = 575 [pid 8449] fstat(575, {st_mode=S_IFREG|0664, st_size=365, ...}) = 0 [pid 8449] pread(575, "?\327l\27\31CompoundFileWriterEntries\0\0"..., 365, 0) = 365 [pid 8449] close(575) = 0 [pid 8449] pread(573, "?\327l\27\22Lucene46FieldInfos\0\0\0\2\20\4_ui"..., 1024, 15956) = 1024 [pid 8449] pread(573, "eldPostingsFormat.suffix\0010\7messa"..., 405, 16980) = 405
进程会在本地频繁的创建、打开、关闭、删除文件
5. 系统的自动slab缓存回收
在slab缓存中,对象分为SReclaimable(可回收)和SUnreclaim(不可回收),而在系统中绝大多数对象都是可回收的。内核有一个参数,当系统内存使用到一定量的时候,会自动触动回收操作。
内核参数:
vm.min_free_kbytes = 836787
6. 恢复
slab机制可以管理分配内存,如果想尽快回收的话则可以执行如下命令:
#sync;sync;sync Linux学习,http:// linux.it.net.cn
#echo 2 > /proc/sys/vm/drop_caches
等内存回收完毕后再执行:
#echo 0 > /proc/sys/vm/drop_caches
其中drop_caches的4个值有如下含义:
0:不做任何处理,由系统自己管理
1:清空pagecache
2:清空dentries和inodes
3:清空pagecache、dentries和inodes
原文:http://374400.blog.51cto.com/364400/1896363