使用cgexec vs cgroup.procs使用cgroup

时间:2015-11-17 14:10:41

标签: java linux linux-kernel cgroups

我昨天遇到了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将JVM的PID cgroup.procs放入cgroup的cgexec文件时大不相同。似乎cgroups报告了之后的内存使用情况>它被放置在cgroup中。

cgroup如何解释内存?似乎在使用cgroup.procs时,会考虑JVM的消耗。另一方面,当在cgroup之外启动JVM并稍后通过将PID写入memory.usage_in_bytes文件将其移入其中时,1024 * 1024 * 4中报告的内存消耗保持为零,直到我按Enter键消费量达到预期的cgroups

此外,top报告的内存消耗与cgclassify报告的内存消耗并不完全相同。

编辑:创建以下C程序并将其用于测试。我看到了同样的结果。如果使用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); } 时,内存利用率>在点击进入之前0。

config.omniauth :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'], scope: 'email', info_fields: 'email, name'

1 个答案:

答案 0 :(得分:1)

当你分配一个页面并且它被一个进程分页时,分配的内存被标记一个标识符,告诉内核这个内存属于哪个特定的内存控制器cgroup(显然内存也属于任何一个内存) cgroup中)。

将进程迁移到新cgroup时,已分配的内存不会更改其标记。 “重新标记”所有东西是非常昂贵的,甚至没有意义(假设一个页面由两个进程共享,而您只将一个页面迁移到另一个cgroup。“新”标记需要什么?它现在被不同cgroup中的两个进程使用......)

因此,如果您正坐在/ sys / fs / cgroup / memory cgroup中(即您的任务组ID在/ sys / fs / cgroup / memory / tasks中提及,而不是在任何子级的任务文件中) cgroup),你分配的任何东西都是那个 cgroup和那个cgroup的。

当您迁移到其他cgroup(或子cgroup)时,只有 new 内存分配被标记为属于该新cgroup。

cgexec将在 cgroup中启动JVM ,因此在初始化时分配的任何内容都将属于为您执行的内容创建的cgroup。

如果在根cgroup中为内存控制器启动JVM,则初始化JVM时分配和触摸的任何内容都属于根cgroup。

将JVM迁移到自己的私有cgroup(使用任一机制)和然后,您可以分配并触摸某些页面,显然这些将属于新的cgroup。