gpt4 book ai didi

c++ - 已释放的堆未被回收?

转载 作者:行者123 更新时间:2023-11-28 00:07:13 28 4
gpt4 key购买 nike

我有一个 C++ 进程可以摄取大块数据并将它们存储在内存中。存储阵列包含大约 10 GB 的数据,分为 4MB block 。当新数据到达时,它会创建一个新 block ,然后在旧 block 已满时将其删除。此过程每 10 - 60 秒在整个循环缓冲区中循环一次。我们在 x86_64 RH5 和 RH6 上运行,并使用 Intel 14 编译器进行编译。

我们发现了一个问题,即整个进程的内存使用量会随着时间的推移而增长,直到操作系统内存不足,最终机器死机。我们一直在寻找内存泄漏并通过 TotalView 运行进程,试图确定内存的去向,但没有看到任何报告的泄漏。

在 total view 生成的堆报告中,我们看到为存储数据分配了 10GB 的内存,但我们也看到了 4+ GB 的“释放”内存。查看堆显示,我们的堆似乎非常零散。将有一大块“已分配”内存散布在大块“已释放”内存中。

  • “解除分配”的内存是否已被我的进程释放但未被操作系统回收,是否有理由认为这可能是我们内存“泄漏”的来源?

  • 如果是这样,我如何让操作系统回收内存?

  • 我们是否需要重新设计流程以重用丢弃的数据 block ,而不是依赖操作系统为我们进行内存管理?

最佳答案

我猜(并希望你)你在 Linux 上(如果将你的代码移植到 Linux 是可行的,考虑一下,因为 Linux 有解决此类问题的好工具)。

然后:

以上内容将帮助您捕获一些剩余的 memory leaks .准备好花几个星期在他们身上。您可能需要禁用 ASLR并且您应该了解 gdb 观察点。

您也可以考虑使用 Boehm's conservative garbage collector .参见 this在标准 C++ 中使用它 containers .如果您确实使用了 Boehm 的 GC,那么您最好在程序的几乎每个地方都使用它...

正品fragmentation可能会发生(即使您确定已经避免了内存泄漏,并且已经检查过,例如使用 valgrind),特别是对于长期存在的进程。在这种情况下,您可能会考虑拥有自己的 application checkpointing设施(这对于重新启动长期计算也很有用)。如果您考虑得足够早(检查点应该是早期的架构设计决策!),您可以偶尔(例如每小时)将您的状态检查点到磁盘并重新启动一个新进程。这可能是一个很好的内存压缩策略。

您可以(但我不一定推荐)在 OS virtual address space 之上编写您自己的内存分配器改 rebase 元如 mmap(2) (可能与 MAP_HUGETLB ....) & munmap;您可能有自己的分配器和释放器(至少对于大型对象,或者有 operator newoperator delete 等...,一些 你的类(class)),阅读 C++ allocator concept .但是你的标准 newdelete (以及 malloc & free 用于 C 代码,通常被 C++ 使用new & delete) 正在使用它们。

请注意,大多数freedelete 不会调用munmap,而只是将释放的内存标记为可由 future 的malloc< 重用new ...

您绝对应该更加熟悉 garbage collection技术和术语。阅读 GC handbook .

另见 mallinfo(3) & mallopt(3) & proc(5) (也许在程序内部使用 /proc/self/maps/proc/self/smaps & /proc/self/statm 来学习关于你的堆,或者 pmap 命令)。也许strace(1)可能会有用(了解 syscalls(2) 发生了什么)

关于c++ - 已释放的堆未被回收?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34906751/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com