使用cgroup控制Linux上的内存使用情况

时间:2015-03-03 22:49:28

标签: linux memory-management process cgroups

我正在尝试使用cgroups来停止实际使用太多内存的程序,同时让它们运行,如果它们只是分配而实际上并没有使用大量内存。但是,它似乎没有用;有什么建议?在Ubuntu机器上,我按如下方式设置了我的cgroup [1]:

#Changing $USER to a system user running the process
sudo apt-get install cgroup-bin
sudo cgcreate -a $USER -g memory:$USER
echo 100M > /cgroup/memory/$USER/memory.limit_in_bytes

#Running the program using cgroups
cgexec -g memory:$USER program

我正在使用以下程序(回答“否”应该起作用,应该停止“是”)。

#include <stdlib.h>
#include <stdio.h>

#define SIZE (long int) 1*1024*1024*1024*sizeof(char)/*1 GB*/

int main(void)
{
  char *str = (char*) malloc(SIZE);
  char *ans = (char*) malloc(100);

  printf("Write random values to memory? (yes/no): ");
  scanf("%s", ans);

  if (strcmp(ans,"yes") == 0) {
    FILE *f = fopen("/dev/urandom","r");
    fread(str,1,SIZE,f);
    printf("Success!!\n");
    fclose(f);
    free(str);
  }
  else {
    printf("Have a good day!\n");
  }

  return(0); 
}

[1] https://askubuntu.com/questions/94619/how-to-set-cpu-limit-for-given-process-permanently-cpulimit-and-nice-dont-work

2 个答案:

答案 0 :(得分:1)

您测试返回成功,因为它不检查错误。事实上,当二进制文件达到内存限制时,fread调用失败。 您可以通过更改代码来检查错误:

#include <stdlib.h>
#include <stdio.h>

#define SIZE (long int) 1*1024*1024*1024*sizeof(char)/*1 GB*/

int main(void)
{
  char *str = (char*) malloc(SIZE);
  char *ans = (char*) malloc(100);

  printf("Write random values to memory? (yes/no): ");
  scanf("%s", ans);

  if (strcmp(ans,"yes") == 0) {
    FILE *f = fopen("/dev/urandom","r");
    int size = fread(str,1,SIZE,f);
    if (size < SIZE) {
        printf("incomplete read: %d, error %d\n", size, ferror(f));
    } else {
        printf("Success!!\n");
    }
    fclose(f);
    free(str);
  }
  else {
    printf("Have a good day!\n");
  }

  return(0);
}

更酷的是使用像cadvisor这样的cgroup监控实用程序你可以用图形方式看到你的二进制文件达到了极限。 cadvisor。希望有所帮助:)

答案 1 :(得分:0)

我认为以下是一个更好的测试程序。它会分配大量内存,如果你回答'y',它会尝试使用它。只是分配内存应该工作,但试图以后实际使用它应该触发OOM杀手。一定要先运行“swapoff”。而不是从/ dev / urandom(需要一段时间)读取,这只是将%256写入每个字节,这应该更快。我没有尝试用cgroups测试这个。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define MiB 1024*1024

#define CHUNK_SIZE (100 * MiB)
#define CHUNKS 100000

void overwrite(char *s, size_t size) {
  for (; size > 0; s++, size--)
    *s = (char) (size % 256); // Vary what's written to prevent optimizations
}

int main() {
  char *chunk[CHUNKS];
  int i;
  int numchunks;
  int result;

  printf("Allocating many memory chunks.\n");
  fflush(stdout);
  for (i = 0; i<CHUNKS; i++) {
    chunk[i] = malloc(CHUNK_SIZE);
    if (!chunk[i]) {
      i--;
      printf("Cannot allocate any more\n");
    }
  }
  numchunks = i;

  printf("Should values be written to memory?\n");
  result = getchar();
  if (result == 'y' || result == 'Y') {
    printf("\nWriting chunks of size %d:\n", (unsigned) CHUNK_SIZE);
    fflush(stdout);
    for (i = 0; i<numchunks; i++) {
      printf(" %d", i);
      fflush(stdout);
      overwrite(chunk[i], CHUNK_SIZE);
    }
  }
  printf("Program exiting\n");
  return 0;
}