【问题标题】:Core dump size is increased after freeing memory that was excluded from the core释放从核心中排除的内存后核心转储大小增加
【发布时间】:2020-11-15 16:56:39
【问题描述】:

我使用 jemalloc 3.6.0-11。 我调用 posix_memalign 来分配一个非常大的块。分配后,我调用madvise(ptr, size, MADV_DONTDUMP); 将这个分配从核心转储中排除。

在释放此内存之前,我调用madvise(ptr, size, MADV_DODUMP);,因为我希望如果这些页面将在未来分配中分配,它们将不会保持标记为 DONTDUMP。

问题是在大多数情况下,我刚刚释放的内存并没有返回给OS(即进程的虚拟内存中仍然包含分配;在/proc//status中分配大小仍然是 VmSize 的一部分);事实证明,核心转储是基于进程的虚拟内存的;所以释放内存后,释放的页面将包含在核心转储中。

有人知道如何解决这个问题吗?

提前致谢!

【问题讨论】:

  • 我不确定madvise 是否真的与此有关。听起来这只是free()d但未返回给操作系统的内存(例如munmap())将继续包含在核心转储中,就像操作系统分配给进程的所有其他内存一样.毕竟,内核无法知道您当前是否正在使用该内存。
  • 我认为您的选择是 (1) 忽略它,(2) 修改或包装 malloc/free 在之后/之前执行 DODUMP/DONTDUMP,(3) 以某种方式安排 malloc 返回您的块当你free()它时到操作系统,(4)绕过malloc,用mmap分配你的块,然后在你完成后自己分配munmap
  • 内存实际分配在哪里?如果它在堆上并且不是使用单独的mmap() 调用创建的,那么调用madvise(ptr, size, MADV_DONTDUMP) 如果不忽略调用则不是一个好主意,因为它可能会导致堆中的其他内存,你可能会很好 需要您的核心转储分析不会被转储,并且您的调用很可能会被忽略,因为它用于堆内存。您是在检查 madvise() 调用的返回值,还是只是假设它们成功了?

标签: c malloc coredump jemalloc


【解决方案1】:

你的内存页面对齐了吗?如果不是 the Linux madvise() man pagemadvise() 将失败:

   EINVAL `addr` is not page-aligned or `length` is negative.

【讨论】:

    【解决方案2】:

    我认为到目前为止,解决您的问题的最简单方法是绕过malloc 并直接使用mmap 分配您的大块,完成后使用munmap。这有几个好处:

    • 您知道您可以独占使用相关页面,而不必担心它们会与堆上的其他内容重叠(取决于您请求的对齐方式和大小),也不用担心malloc 的元数据可能在哪里。特别是,您可以随意madvise 他们,而不会影响其他任何事情。

    • 对于一个非常大的块,如果您可以在完成后立即将其返回到操作系统,这对系统的其余部分来说是有礼貌的,而您的 malloc 可能(就像它似乎正在做的那样)坐着用于以后的分配,也许你永远不会这样做。

    • munmap这个块肯定会确保它不会被转储。

    实际上不应该有任何性能问题,因为对于一个非常大的块,posix_memalign 几乎肯定必须从操作系统获取内存,所以无论如何都会有一个系统调用,听起来像你不会非常频繁地分配和释放它。

    【讨论】:

    • 听起来很有趣,我会试试的。谢谢!
    猜你喜欢
    • 2019-07-28
    • 1970-01-01
    • 1970-01-01
    • 2013-09-03
    • 1970-01-01
    • 2011-06-09
    • 2020-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多