简体   繁体   English

free() 后堆中断不会改变吗?

[英]Heap break will not change after free()?

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: 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): Strace 片段(排除的库加载):

 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.).正如我们所见,当 memory 被分配时,堆中断增加(strace 显示第一次分配由 mmap 完成,也由 munmap 释放,第二次分配由 brk 完成。没有第三次分配。)。

But I don't see heap break decreases when free() is called.但是当调用 free() 时,我没有看到堆中断减少。

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?是不是像 kernel 没有释放 memory 以防将来分配该过程?

If yes is there a way to forcefully release the heap once freed by any kernel setting?如果是,有没有办法在任何 kernel 设置释放后强制释放堆?

Not by using standard C.不使用标准 C。 glibc you can use malloc_trim function. glibc 你可以使用malloc_trim function。

https://man7.org/linux/man-pages/man3/malloc_trim.3.html https://man7.org/linux/man-pages/man3/malloc_trim.3.html

You can set the threshold using mallopt function.您可以使用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)如果您设置mallopt(M_TRIM_THRESHOLD, 0)您的程序将在您使用 free 时将 memory 释放到系统(不完全是 - 一些 memory 仍将保留)

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.考虑以下场景:您在酒店预订了 1 天的房间,然后在返回关键时刻后,您想再次预订房间。 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. free并不意味着下次如果您致电malloc它将为您提供旧地址。 It just inform the memory management system that you no longer need the memory allocated before.它只是通知memory management system您不再需要之前分配的 memory。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM