Why can't I free this big block of memory

Recently, I have discovered a strange error while debugging a program. We allocate a large buffer. After freeing the memory, the memory did not return to the OS. And then the next distribution may fail due to lack of memory. Then I did the following test program. I allocated memory for the pointer cand not freeto simulate my real program. (My program has a small memory leak caused by OpenMPI calls.)

It will fail on line 18 on a computer (Mac) with 3 GB of free memory due to insufficient memory. I know that a pointer ccan cause memory fragmentation. But for these large memory buffers, such as aand b, they are allocated mmap, not brk. They should be able to free themselves directly, right? What to do to solve this problem?

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

int main(){

    float *a=malloc(1250000000);
    memset(a, (char)1, 1250000000);

    float *b=malloc(1250000000);
    memset(b, (char)1, 1250000000);

    float *c=malloc(10);
    memset(c, (char)1, 10);

    free(b);
    free(a);

    float *d=malloc(2000000000);  /* FAILS HERE */
    memset(d, (char)1, 2000000000);
}
+4
source share
1 answer

, Mac. , OS X, , . mmap calloc, free munmap, .

, dtruss:

$ dtruss -f -t mmap ./a.out 
    PID/THRD  SYSCALL(args)          = return
57843/0x16bf38:  mmap(0x10C119000, 0x2000, 0x5, 0x12, 0x3, 0x1000)       = 0x10C119000 0
57843/0x16bf38:  mmap(0x10C11B000, 0x1000, 0x3, 0x12, 0x3, 0x3000)       = 0x10C11B000 0
57843/0x16bf38:  mmap(0x10C11C000, 0x1FC0, 0x1, 0x12, 0x3, 0x4000)       = 0x10C11C000 0

$

mmap. brk sbrk, munmap:

$ dtruss -f -t brk ./a.out 
    PID/THRD  SYSCALL(args)          = return

$ dtruss -f -t sbrk ./a.out 
    PID/THRD  SYSCALL(args)          = return

$ dtruss -f -t munmap ./a.out 
    PID/THRD  SYSCALL(args)          = return

$
+2

All Articles