【问题标题】:In what circumstances can malloc_trim(0) cause a crash?在什么情况下 malloc_trim(0) 会导致崩溃?
【发布时间】:2023-02-23 03:54:06
【问题描述】:

我有一段代码,我正在使用 malloc_trim(0) 将任何未使用的内存释放回系统。 但是我断断续续地看到它会导致崩溃。回溯如下:

Program terminated with signal SIGSEGV, Segmentation fault.
#0  mtrim (pad=0, av=0xffff8eebf9f8 <main_arena>) at malloc.c:4771
4771                INTERNAL_SIZE_T size = chunksize (p);

#0  mtrim (pad=0, av=0xffff8eebf9f8 <main_arena>) at malloc.c:4771
#1  __malloc_trim (s=s@entry=0) at malloc.c:4822

我想知道这次崩溃的原因以及如何避免它。

我检查了 malloc_trim() 的手册页,它看起来不会导致崩溃。

【问题讨论】:

  • 没有代码这是不可能的。
  • 代码?代码?代码?
  • 为什么使用malloc_trim()

标签: c memory-management malloc free brk


【解决方案1】:

这是malloc_trim()的手册页:

MALLOC_TRIM(3) Linux 程序员手册 MALLOC_TRIM(3)

姓名

malloc_trim - 从堆顶释放空闲内存

概要

#include <malloc.h>

int malloc_trim(size_t pad);

描述

malloc_trim() 函数尝试释放堆顶部的空闲内存(通过使用合适的参数调用 sbrk(2))。

pad 参数指定在堆顶部保留未修剪的可用空间量。如果此参数为0,则堆顶部仅保留最小内存量(即一页或更少)。非零参数可用于在堆顶部保留一些尾随空间,以便将来进行分配而不必使用 sbrk(2) 扩展堆。

返回值

malloc_trim()函数返回1如果内存实际上被释放回系统,或者0如果不可能释放任何内存。

错误

没有定义错误。

符合

这个函数是一个 GNU 扩展。

笔记

该函数在某些情况下由free(3)自动调用;请参阅mallopt(3)M_TOP_PADM_TRIM_THRESHOLD的讨论。

此函数无法释放位于堆顶部以外的其他位置的空闲内存。

此函数仅释放主区域中的内存。

0 是这个 GNU 扩展函数的完美论据。报告的错误似乎表明堆已损坏,这可能是由您的程序在调用 malloc_trim() 之前引起的。这些错误可能是:

  • 修改已分配块末尾或开头之前的字节
  • 块被释放后的修改
  • 同一块的多个释放

您应该使用 valgrind 等内存工具进行调查,以确定这些问题。

另请注意,malloc_trim() 不可移植,并且在实践中兴趣有限,因为它仅修剪由 sbrk() 分配的遗留堆。现代分配器使用 mmap 来分配不同的区域,并且应该自动处理将未使用的页面释放回操作系统。

【讨论】:

    猜你喜欢
    • 2021-06-28
    • 1970-01-01
    • 2012-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-03
    相关资源
    最近更新 更多