Linux

fork 에러 (Cannot allocate memory)

알모리 2017. 7. 31. 15:31

fork() 후에 exec() 을 호출 하기 전까지는 child 프로세스는 parent 와 동일한 크기의 virtual memory 를 점유 하며, exec() 이후에 실행 파일에 따른 메모리를 새로 점유 한다.

따라서 fork() 시점에 parent 가 memory를 많이 쓰고 있는 경우, 시스템에 메모리가 부족하면 fork 가 실패 할 수 있다. fork fail(-1), error:12, (Cannot allocate memory)


#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
 
#define MB 1024*1024
 
int main(int argc, char **argv)
{
    char *p = NULL;
    pid_t pid = 0;
    int size = 0;
 
    if (argc == 2) {
        size = atoi(argv[1]);
    else {
        size = 100;
    }
 
    fprintf(stderr, "try malloc %d MB\n", size);
 
    p = malloc(size * MB);
    if (p == NULL) {
        fprintf(stderr, "malloc(%d MB) fail\n", size);
        exit(1);
    }
 
    memset(p, 0, size * MB);
 
    fprintf(stderr, "check memory of parent process\n");
    fprintf(stderr, "grep Vm /proc/%d/status\n", getpid());
    sleep(10);
 
    pid = fork();
 
    if (pid < 0) {
        // fail
        fprintf(stderr, "fork fail(%d), error:%d, (%s)\n", pid, errno, strerror(errno));
        exit(0);
 
    else if (pid == 0) {
        // child
        //sleep(10);
        char *aa[] = {"sleep""10", NULL};
 
        fprintf(stderr, "check memory of child process\n");
        fprintf(stderr, "grep Vm /proc/%d/status\n", getpid());
        sleep(10);
 
        fprintf(stderr, "child will execvp(\"sleep 20\")\n");
        execvp("sleep", aa);
 
        // never reach this
        exit(0);
    else {
        // parent
        int status;
 
        fprintf(stderr, "parent will wait child\n");
        waitpid(pid, &status, 0);
    }

}


1100 MB 를 할당한 상태의 Parent Process 메모리 확인
 
~/debug #
try malloc 100 MB
check memory of parent process
grep Vm /proc/8823/status
grep Vm /proc/8823/status
VmPeak:   107060 kB
VmSize:   107060 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:    103352 kB
VmRSS:    103352 kB
VmData:   103808 kB
VmStk:       136 kB
VmExe:         4 kB
VmLib:      2688 kB
VmPTE:       112 kB
VmPMD:         0 kB
VmSwap:        0 kB
~/debug #
parent will wait child
 
 
2. fork 이후에 Child Process 의 메모리 확인
 
check memory of child process
grep Vm /proc/8852/status
 
~/debug # grep Vm /proc/8852/status
VmPeak:   107060 kB
VmSize:   107060 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:    102580 kB
VmRSS:    102580 kB
VmData:   103808 kB
VmStk:       136 kB
VmExe:         4 kB
VmLib:      2688 kB
VmPTE:       110 kB
VmPMD:         0 kB
VmSwap:        0 kB
~/debug #
 
3. child process가 exec을 수행하여 process image를 변경 한 후에 메모리 확인
 
child will execvp("sleep 20")
grep Vm /proc/8852/status
VmPeak:     5116 kB
VmSize:     5116 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:       948 kB
VmRSS:       948 kB
VmData:     1412 kB
VmStk:       136 kB
VmExe:       456 kB
VmLib:      2688 kB
VmPTE:        10 kB
VmPMD:         0 kB
VmSwap:        0 kB