3. memory

Subsystem - memory

memory 서브시스템은 cgroup에서 사용하는 메모리 자원에 대해 프로세스가 사용하는 메모리 양과 사용 가능한 메모리 자원을 컨트롤 할 수 있습니다. 또한 사용되는 메모리 자원에 대한 레포트도 자동으로 생성해주는 서브시스템입니다.

memory 서브시스템은 시스템으로부터 태스크의 그룹의 메모리 접근등의 동작을 격리화시킵니다. 이 서브시스템이 사용되는 경우는 다음과 같습니다.

  • 메모리 소모가 많은 어플리케이션을 격리하고 더 작은 어플리케이션으로 제한할 수 있습니다.
  • mem=XXXX 설정을 통해 부팅하는 경우의 좋은 대안이 될 수 있습니다.
  • 가상화 솔루션에서 원하는 메모리 양을 제어할 수 있습니다. 위 내용 외에도 여러 요소가 있을 수 있습니다.

예제 살펴보기

  1. cgroup 가상파일시스템을 마운트합니다.
$ sudo mkdir -p /cgroup/memory
$ sudo mount -t cgroup -o memory memory /cgroup/memory
  1. 마운트 여부 확인하기. 아래 명령어를 수행해서 결과가 표시된다면 정상적으로 마운트되었습니다.
$ mount | grep cgroup
memory on /cgroup/memory type cgroup (rw,relatime,blkio)
or
$ cat /proc/mount | grep cgroup
memory /cgroup/memory cgroup rw,relatime,blkio 0 0
  1. mount 상태 확인해보기.
linuxias@linuxias-VirtualBox:/cgroup/memory$ ls -al
total 4
dr-xr-xr-x 2 root root    0  8월 11 13:35 .
drwxr-xr-x 4 root root 4096  8월 11 15:49 ..
-rw-r--r-- 1 root root    0  8월 11 15:49 cgroup.clone_children
--w--w--w- 1 root root    0  8월 11 15:49 cgroup.event_control
-rw-r--r-- 1 root root    0  8월 11 13:35 cgroup.procs
-r--r--r-- 1 root root    0  8월 11 15:49 cgroup.sane_behavior
-rw-r--r-- 1 root root    0  8월 11 15:49 memory.failcnt
--w------- 1 root root    0  8월 11 15:49 memory.force_empty
-rw-r--r-- 1 root root    0  8월 11 15:49 memory.kmem.failcnt
-rw-r--r-- 1 root root    0  8월 11 15:49 memory.kmem.limit_in_bytes
-rw-r--r-- 1 root root    0  8월 11 15:49 memory.kmem.max_usage_in_bytes
-r--r--r-- 1 root root    0  8월 11 15:49 memory.kmem.slabinfo
-rw-r--r-- 1 root root    0  8월 11 15:49 memory.kmem.tcp.failcnt
-rw-r--r-- 1 root root    0  8월 11 15:49 memory.kmem.tcp.limit_in_bytes
-rw-r--r-- 1 root root    0  8월 11 15:49 memory.kmem.tcp.max_usage_in_bytes
-r--r--r-- 1 root root    0  8월 11 15:49 memory.kmem.tcp.usage_in_bytes
-r--r--r-- 1 root root    0  8월 11 15:49 memory.kmem.usage_in_bytes
-rw-r--r-- 1 root root    0  8월 11 13:35 memory.limit_in_bytes
-rw-r--r-- 1 root root    0  8월 11 15:49 memory.max_usage_in_bytes
-rw-r--r-- 1 root root    0  8월 11 15:49 memory.move_charge_at_immigrate
-r--r--r-- 1 root root    0  8월 11 15:49 memory.numa_stat
-rw-r--r-- 1 root root    0  8월 11 15:49 memory.oom_control
---------- 1 root root    0  8월 11 15:49 memory.pressure_level
-rw-r--r-- 1 root root    0  8월 11 15:49 memory.soft_limit_in_bytes
-r--r--r-- 1 root root    0  8월 11 15:49 memory.stat
-rw-r--r-- 1 root root    0  8월 11 15:49 memory.swappiness
-r--r--r-- 1 root root    0  8월 11 15:49 memory.usage_in_bytes
-rw-r--r-- 1 root root    0  8월 11 13:35 memory.use_hierarchy
-rw-r--r-- 1 root root    0  8월 11 15:49 notify_on_release
-rw-r--r-- 1 root root    0  8월 11 15:49 release_agent
-rw-r--r-- 1 root root    0  8월 11 15:49 tasks

마운트한 디렉토리에서 내부 리스트를 확인해보니 위와 같이 많은 파일들이 생성되었습니다. 그 중 우리가 write할 수 있는 파일은 몇 개 되지 않네요. 나머지는 모두 read만 할 수 있습니다. 그 말은 우리가 cgroup blkio 서브시스템을 사용하여 제어할 수 있는 요소들은 write 권한이 있는 파일들을 유심히 보면 될 것 같습니다.

  1. 특정 프로세스의 메모리 설정하기.
$ sudo mkdir /cgroup/memory/test_process
$ sudo echo 1G > /cgroup/memory/test_process/memory.limit_in_bytes
$ cat /cgroup/memory/test_process/memory.limit_in_bytes
1073741824
  1. cgroup에 적용하기. test process의 pid가 10001 이라고 할 때 아래와 같이 설정해 줍니다.
$ echo 10001 >> /cgroup/memory/test_process/tasks

위와 같이 설정하거나 프로세스의 이름이 test 라고 할 때

$pidof test | while read PID; do echo $PID >> /cgroup/memory/test_process/tasks; done

memory 서브시스템 statistics 확인해보기.

memory.stat 파일에는 다양한 통계 정보가 존재합니다. 아래와 같이 확인 하실 수 있습니다.

$ cat memory.stat 
cache 912625664
rss 281018368
rss_huge 0
shmem 1433600
mapped_file 178327552
dirty 0
writeback 0
pgpgin 915786
pgpgout 624369
pgfault 1014204
pgmajfault 2469
inactive_anon 536576
active_anon 280662016
inactive_file 379850752
active_file 521773056
unevictable 10792960
hierarchical_memory_limit 9223372036854771712
total_cache 912625664
total_rss 281018368
total_rss_huge 0
total_shmem 1433600
total_mapped_file 178327552
total_dirty 0
total_writeback 0
total_pgpgin 915786
total_pgpgout 624369
total_pgfault 1014204
total_pgmajfault 2469
total_inactive_anon 536576
total_active_anon 280662016
total_inactive_file 379850752
total_active_file 521773056
total_unevictable 10792960

각 정보에 대한 설명은 Documentation file 5.2 stat file 를 참고해주세요.

memory 파일 설명

아래 몇 가지 파일에 대한 내용을 표로 작성해두었습니다. 그 외 다른 파일에 대한 설명은 Documentation을 보시면 좋습니다.

파일 설명
tasks 태스크를 추가하고, 스레드의 리스트를 볼 수 있습니다.
cgroup.procs 프로세스들의 리스트를 볼 수 있습니다.
cgroup.event_control event_fd() 를 위한 인터페이스 입니다.
memory.usage_in_bytes 현재 메모리 사용량을 표시합니다.
memory.memsw.usage_in_bytes 현재 memory+swap 사용량을 보여줍니다.
memory.limit_in_bytes 메모리 사용량의 제한을 설정 또는 보여줍니다.
memory.memsw.limit_in_bytes memory + swap 메모리 사용량의 제한을 설정 또는 보여줍니다.
memory.failcnt 메모리 사용량 hits 제한을 보여줍니다.
memory.memsw.failcnt memory + swap 메모리 사용량 hits 제한을 보여줍니다.
memory.max_usage_in_bytes 최대 메모리 사용량을 보여줍니다.
memory.memsw.max_usage_in_bytes memory + swap 메모리의 최대 사용량을 보여줍니다.
memory.soft_limit_in_bytes 메모리 사용의 소프트 제한을 설정 또는 보여줍니다.
memory.stat 다양한 statistics를 보여줍니다.
memory.use_hierarchy 자식 프로세스의 메모리 여부를 설정 또는 보여줍니다.
memory.force_empty 0으로 설정하면 작업에서 사용하는 메모리를 해제합니다.
memory.pressure_level 메모리 입력 알람을 설정합니다.
memory.oom_control oom 제어를 설정또는 보여줍니다.
memory.numa_stat Numa 노드 당 메모리 사용의 수를 보여줍니다
memory.kmem.limit_in_bytes 커널 메모리에 대한 hard limit을 설정 또는 보여줍니다.
memory.kmem.usage_in_bytes 현재 커널 메모리 할당을 보여줍니다.
memory.kmem.failcnt 커널 메모리 사용 hits 제한의 수를 보여줍니다.
memory.kmem.max_usage_in_bytes 커널 메모리 사용의 max 값을 보여줍니다.

이 외에도 매우 많은 파일들이 존재하는데요. 필요한 내용은 Documentation을 꼭 참고해주세요.

참고자료