Code:
int main() {
printf("entering main. %p\n", sbrk(0));
void* ptr = malloc(300 * 1024);
memset(ptr, 0xBE, 300 * 1024);
printf("Allocated memory. %p\n", sbrk(0));
free(ptr);
printf("Freed memory. %p\n", sbrk(0));
void* ptr1 = malloc(300 * 1024);
memset(ptr1, 0xBE, 300 * 1024);
printf("Allocated memory. %p\n", sbrk(0));
free(ptr1);
printf("Freed memory. %p\n", sbrk(0));
void* ptr2 = malloc(300 * 1024);
memset(ptr2, 0xBE, 300 * 1024);
printf("Allocated memory. %p\n", sbrk(0));
free(ptr2);
printf("Freed memory. %p\n", sbrk(0));
printf("exiting main. %p\n", sbrk(0));
}
Output:
entering main. 0x2403000
Allocated memory. 0x2424000
Freed memory. 0x2424000
Allocated memory. 0x246f000
Freed memory. 0x246f000
Allocated memory. 0x246f000
Freed memory. 0x246f000
exiting main. 0x246f000
Strace snippet(excluded lib loads):
0.000064 [00007fc92fa32f19] brk(NULL) = 0x2403000
0.000033 [00007fc92fa2cd34] fstat(1</dev/pts/33>, {st_dev=makedev(0, 14), st_ino=36, st_mode=S_IFCHR|0620, st_nlink=1, st_uid=60141191, st_gid=5, st_blksize=1024, st_blocks=0, st_rdev=makedev(136, 33), st_atime=2022/08/11-11:19:36.874073993, st_mtime=2022/08/11-11:19:36.874073993, st_ctime=2022/08/11-10:34:22.874073993}) = 0
0.000084 [00007fc92fa32f19] brk(0x2424000) = 0x2424000
0.000026 [00007fc92fa2d3c0] write(1</dev/pts/33>, "entering main. 0x2403000\n", 25) = 25
0.000040 [00007fc92fa377ba] mmap(NULL, 311296, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc92fead000
0.000200 [00007fc92fa2d3c0] write(1</dev/pts/33>, "Allocated memory. 0x2424000\n", 28) = 28
0.000034 [00007fc92fa37847] munmap(0x7fc92fead000, 311296) = 0
0.000042 [00007fc92fa2d3c0] write(1</dev/pts/33>, "Freed memory. 0x2424000\n", 24) = 24
0.000052 [00007fc92fa32f19] brk(0x246f000) = 0x246f000
0.000200 [00007fc92fa2d3c0] write(1</dev/pts/33>, "Allocated memory. 0x246f000\n", 28) = 28
0.000031 [00007fc92fa2d3c0] write(1</dev/pts/33>, "Freed memory. 0x246f000\n", 24) = 24
0.000033 [00007fc92fa2d3c0] write(1</dev/pts/33>, "Allocated memory. 0x246f000\n", 28) = 28
0.000043 [00007fc92fa2d3c0] write(1</dev/pts/33>, "Freed memory. 0x246f000\n", 24) = 24
0.000030 [00007fc92fa2d3c0] write(1</dev/pts/33>, "exiting main. 0x246f000\n", 24) = 24
0.000036 [00007fc92fa027c8] exit_group(0) = ?
As we can see the heap break is increased when the memory is allocated (strace shows first allocation done by mmap also freed by munmap and second allocation done by brk. and there is no third allocation.).
But I don't see heap break decreases when free() is called.
I would like to know the reason for this behavior. Is it like kernel not freeing memory in case of future allocation for the process?
CodePudding user response:
If yes is there a way to forcefully release the heap once freed by any kernel setting?
Not by using standard C. glibc you can use malloc_trim
function.
https://man7.org/linux/man-pages/man3/malloc_trim.3.html
You can set the threshold using mallopt
function.
If you set mallopt(M_TRIM_THRESHOLD, 0)
your program will release the memory to the system when you use free (not exactly - some memory will still be kept)
CodePudding user response:
Consider the following scenario: You book a room in hotel for 1 day, then after return the key few moment, you want to book a room again. Now there is possibility that you will be able to book to a different room than the previous one.
free
does not mean that next time if you call malloc
it will provide the old address to you. It just inform the memory management system
that you no longer need the memory allocated before.