昨天我在使用 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);
}
}
使用 运行上述程序时,内存使用情况与将 JVM 的 PID 写入cgroup 的文件cgexec
时有很大不同。似乎 cgroup 在将进程放入 cgroup后会报告进程的内存使用情况。echo
cgroup.procs
cgroup 如何占内存?似乎在使用时cgexec
,JVM 的消耗被考虑在内。另一方面,当在 cgroup 之外启动 JVM 并稍后通过将 PID 写入cgroup.procs
文件将其移动到其中时,报告的内存消耗memory.usage_in_bytes
保持为零,直到我按 enter 并且消耗1024 * 1024 * 4
按预期上升。
此外,例如,报告的内存消耗与报告的内存消耗cgroups
并不完全相同top
。
编辑:创建了以下 C 程序并将其用于测试。我看到了同样的结果。如果使用cgclassify
,则内存利用率保持为 0 直到回车。另一方面,当使用 时cgexec
,在按回车之前内存利用率 > 0。
#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);
}