jvm(일반 애플리케이션)이 실행 중인 서버에서 slab memory가 끊임없이 늘어나는 현상이 발견되었다.



* slab 메모리가 있는지 확인하기 위해 다음 링크를 참조하면 쉽게 slab 메모리 정보를 구할 수 있다. (/proc/meminfo에서 Slab 영역을 얻는다)

http://atomitech.jp/hinemos/blog/?cat=12


#!/bin/bash

total=`cat /proc/meminfo | grep MemTotal | awk '{print $2}'`
free=`cat /proc/meminfo | grep MemFree | awk '{print $2}'`
buff=`cat /proc/meminfo | grep Buffers | awk '{print $2}'`
cache=`cat /proc/meminfo | grep ^Cached | awk '{print $2}'`
slab=`cat /proc/meminfo | grep Slab | awk '{print $2}'`
used=`echo "scale=2; ($total - $free - $buff - $cache - $slab) * 100 / $total" | bc`
echo "used,$used"






참고로 jvm 메모리 상태를 확인하며 gc 여부를 확인했지만 특별히 변경 내역은 없었다.


$ jstat -gc 프로세스-id 1 1

 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT

 0.0   2048.0  0.0   2048.0 2383872.0 624640.0 1808384.0  1099923.5  61056.0 60410.3 7296.0 7135.3  32873  338.821   3      0.999  339.821

 



jvm은 이슈가 아닌 것 같고, vmstat으로 메모리 상태를 확인했다. 

각 필드의 항목 내용은 Num  Total   Size  Pages이다. 확실히 개수와 용량이 늘긴 늘었다

(vmstat 참고 : https://www.thomas-krenn.com/en/wiki/Linux_Performance_Measurements_using_vmstat#vmstat_-m)



$ vmstat -m  | grep proc_inode_cache

proc_inode_cache         4511372 4513830    656      6




다른 장비에서 동일한 명령어를 실행해서 동일하게 메모리를 확인했다. 


$ vmstat -m  | grep proc_inode_cache

proc_inode_cache          17500  17514    656      6




확실히 inode 캐시 값이 너무 커졌다. 이를 정리하기 위해 운영 체제의 vfs_cache_pressure를 사용해야 했다.



==============================================================

vfs_cache_pressure
------------------

This percentage value controls the tendency of the kernel to reclaim
the memory which is used for caching of directory and inode objects.

At the default value of vfs_cache_pressure=100 the kernel will attempt to
reclaim dentries and inodes at a "fair" rate with respect to pagecache and
swapcache reclaim.  Decreasing vfs_cache_pressure causes the kernel to prefer
to retain dentry and inode caches. When vfs_cache_pressure=0, the kernel will
never reclaim dentries and inodes due to memory pressure and this can easily
lead to out-of-memory conditions. Increasing vfs_cache_pressure beyond 100
causes the kernel to prefer to reclaim dentries and inodes.

Increasing vfs_cache_pressure significantly beyond 100 may have negative
performance impact. Reclaim code needs to take various locks to find freeable
directory and inode objects. With vfs_cache_pressure=1000, it will look for
ten times more freeable objects than there are.

 




jvm이 통신하면서 임시로 메모리 공간(pagecache)을 사용한 것 같은데, 정리가 안되면서 커진 것 같았다.  캐시 데이터는 centos 내부적으로 slab 메모리로 관리된다. inode가 커널의 slab 메모리에서 관리되기 때문에 inode와 slab 메모리가 상당히 커진 것 같았다. 


vfs_cache_pressure는 pagecache를 반환하려는 값이 저장되어 있다. 기본값은 100이다. 위의 문서에 설명되어 있듯이 0이면, 메모리 반환을 하지 않고, 1000을 설정하면 계속 free공간으로 메모리를 반환하려 한다.



나는 아래와 같이 값을 큰 값을 주어 자연스럽게 slab 메모리가 빨리 정리되게 했다. 


$ echo 10000 > /proc/sys/vm/vfs_cache_pressure



문제는 전혀 발생하지 않았고, slab 메모리를 깔끔히 정리되었다. 


이 외에 다른 방법이 있다고 한다. 



https://community.oracle.com/thread/3553285?start=0&tstart=0


To free pagecache: echo 1 > /proc/sys/vm/drop_caches

To free reclaimable slab objects (includes dentries and inodes): echo 2 > /proc/sys/vm/drop_caches

To free slab objects and pagecache: echo 3 > /proc/sys/vm/drop_caches





참고로 hbase에서는 이슈가 있었다고 하니. 부하가 높은 상황에서는 조심히 사용할 필요는 있을 것 같다. 


https://brunch.co.kr/@alden/14





Posted by '김용환'
,