Вчера столкнулся с интересной ситуацией с контроллером памяти cgroups. Я всегда думал, что память, сообщаемая cgroups, была общим потреблением памяти процессами, но похоже, что это не так.
Я написал следующее программирование на Java для тестирования:
import java.util.Scanner;
class TestApp {
public static void main(String args[]) {
int[] arr;
Scanner in = new Scanner(System.in);
System.out.println("Press enter to allocate memory");
in.nextLine();
arr = new int[1024*1024];
System.out.println("Allocated memory");
while(true);
}
}
При выполнении вышеуказанного с cgexec
использование памяти сильно отличается от использования памяти при echo
вставке PID JVM в файл cgroup.procs
cgroup. Похоже, контрольные группы сообщают об использовании памяти процессом после его помещения в контрольную группу.
Как cgroup учитывает память? Похоже, что при использовании cgexec
учитывается потребление JVM. С другой стороны, при запуске JVM вне контрольной группы и перемещении ее в нее позже путем записи PID в файл cgroup.procs
потребление памяти, указанное в memory.usage_in_bytes
, остается нулевым, пока я не нажму Enter, и потребление не увеличится до 1024 * 1024 * 4
, как и ожидалось. .
Кроме того, потребление памяти, о котором сообщает cgroups
, не полностью совпадает с потреблением памяти, о котором сообщает, например, top
.
Изменить: создал следующую программу на C и использовал ее для тестирования. Я вижу те же результаты. При использовании cgclassify
использование памяти остается равным 0 до тех пор, пока не будет нажата клавиша ввода. С другой стороны, при использовании cgexec
использование памяти > 0 перед нажатием Enter.
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Press ENTER to consume memory\n");
getchar();
char *ptr = malloc(1024*1024);
if (ptr == NULL) {
printf("Out of memory");
exit(1);
}
memset(ptr, 0, 1024*1024);
printf("Press ENTER to quit\n");
getchar();
return(0);
}