memory 서브시스템(memcg)은 프로세스 그룹의 메모리 리소스를 효율적으로 관리하는 기능이다. 이를 통해 메모리 사용량을 제한하고, Out-of-Memory(OOM) 상황을 방지할 수 있다. 또한 메모리 사용량 모니터링을 통해 리소스 사용 상태를 파악할 수 있으며, 메모리 압출 및 Swap 설정을 통해 메모리 최적화를 할 수 있다.
메모리 제한 설정
프로세스 그룹에 할당되는 메모리의 양을 제한할 수 있다. 이를 위해 memory.limit_in_bytes
파일을 사용한다.
/sys/fs/cgroup/memory/[cgroup_name]/memory.limit_in_bytes
:- 프로세스 그룹에 할당되는 최대 메모리 양을 바이트 단위로 설정
- 예를 들어, 1GB는 1,073,741,824로 표기
메모리 제한 설정 예시:
$ echo 1073741824 > /sys/fs/cgroup/memory/example_group/memory.limit_in_bytes
메모리 사용량 모니터링
memcg는 프로세스 그룹의 메모리 사용량을 모니터링할 수 있다. memory.usage_in_bytes
파일을 통해 사용량을 확인할 수 있으며, 바이트 단위로 표시된다. 예를 들어, 536870912는 512MB를 의미한다.
메모리 사용량 확인 예시:
$ cat /sys/fs/cgroup/memory/example_group/memory.usage_in_bytes
메모리 Threshold 설정
memcg 서브시스템은 cgroups notification API를 사용하여 메모리 threshold 를 구현한다. 이를 통해 이를 통해 메모리 및 메모리 Swap Threshold 를 등록하고, 이를 넘을 때 알림을 받을 수 있다.
메모리 Threshold를 등록하는 방법은 다음과 같다.
- eventfd(2)를 사용하여 eventfd를 생성한다.
memory.usage_in_bytes
또는memory.memsw.usage_in_bytes
를 연다.- “<eventfd> <
memory.usage_in_bytes
의 fd> <threshold>” 같은 문자열을 cgroup.event_control에 write한다.
메모리 사용량이 등록한 Threshold 값을 넘게되면, eventfd를 통해 notify된다. 애플리케이션은 이를 통해 threshold에 대한 action을 취할 수 있다.
Example:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/eventfd.h>
#define CGROUP_PATH "/sys/fs/cgroup/memory/example_group/"
#define THRESHOLD_VALUE 1073741824 // 1GB
int main() {
// Create eventfd
int event_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
if (event_fd == -1) {
perror("Failed to create eventfd");
return 1;
}
// Open memory.usage_in_bytes
char usage_path[256];
sprintf(usage_path, "%s/memory.usage_in_bytes", CGROUP_PATH);
int usage_fd = open(usage_path, O_RDONLY);
if (usage_fd == -1) {
perror("Failed to open memory.usage_in_bytes");
return 1;
}
// Open cgroup.event_control
char event_control_path[256];
sprintf(event_control_path, "%s/cgroup.event_control", CGROUP_PATH);
int event_control_fd = open(event_control_path, O_WRONLY);
if (event_control_fd == -1) {
perror("Failed to open cgroup.event_control");
return 1;
}
// Register threshold
char event_control_str[256];
sprintf(event_control_str, "%d %d %lu", event_fd, usage_fd, THRESHOLD_VALUE);
if (write(event_control_fd, event_control_str, strlen(event_control_str)) == -1) {
perror("Failed to write to cgroup.event_control");
return 1;
}
printf("Threshold registered successfully\n");
// Wait for event
uint64_t event_value;
if (read(event_fd, &event_value, sizeof(event_value)) == -1) {
perror("Failed to read eventfd");
return 1;
}
printf("Threshold crossed\n");
// Close file descriptors
close(event_fd);
close(usage_fd);
close(event_control_fd);
return 0;
}
OOM (Out-of-Memory) 제어
memcg 서브시스템은 OOM 상황에서의 동작을 제어할 수 있다. OOM 상황은 시스템의 메모리가 부족한 상황에서 발생하며, 이를 효과적으로 관리하기 위해 memory.oom_control
파일을 사용한다.
/sys/fs/cgroup/memory/[cgroup_name]/memory.oom_control
:- OOM 상황에서 프로세스 그룹의 동작을 제어
0
으로 설정하면 OOM 상황에서 프로세스를 종료시킨다.
OOM 제어 설정 예시:
$ echo 0 > /sys/fs/cgroup/memory/example_group/memory.oom_control
메모리 압축 및 스왑 설정
cgroup Memory 서브시스템은 메모리 압축과 스왑을 제어할 수 있다. 메모리 압축은 더 많은 데이터를 메모리에 저장하는 기술이며, 스왑은 메모리 부족 상황에서 디스크 공간을 사용하여 메모리를 보조하는 기술이다. 이를 제어하기 위해 memory.swappiness
파일을 사용한다.
/sys/fs/cgroup/memory/[cgroup_name]/memory.swappiness
:- 스왑 사용 정도를 설정하는 파일
0
은 스왑을 사용하지 않음을 의미하고,100
은 스왑을 최대한 사용함을 의미
메모리 압축 및 스왑 설정 예시:
$ echo 50 > /sys/fs/cgroup/memory/example_group/memory.swappiness
cgroups: 프로세스 그룹의 자원 관리
cgroup: cpu 서브시스템
cgroup: memory 서브시스템
cgroups: Memory Threshold Notifier 구현
cgruops v1 사용법