gpt4 book ai didi

linux - 在 GHC 的堆分析器的 View 之外可能发生哪些内存泄漏

转载 作者:行者123 更新时间:2023-12-05 03:32:31 26 4
gpt4 key购买 nike

我有一个程序表现出内存泄漏的行为。它逐渐占用所有系统内存,直到填满所有交换空间,然后操作系统将其杀死。这种情况每隔几天发生一次。

我已经以多种方式(-hy、-hm、-hc)对堆进行了广泛的剖析,并尝试限制堆大小(-M128M)调整世代数(-G1),但无论我做什么堆大小始终保持不变且较低(以 kB 为单位,而不是 MB 或 GB)。然而,当我在 htop 中观察程序时,它的常驻内存在稳步攀升。

这向我表明内存泄漏来自 GHC 堆之外的某个地方。我的程序使用了依赖项,特别是包装了 C 库 libyaml 的 Haskell 的 yaml 库,泄漏可能在于它必须分配给对象的外部指针的数量通过 libyaml

我的问题有三个:

  1. Haskell 程序中除了 GHC 堆之外还有哪些地方可能发生内存泄漏?
  2. 我可以使用什么工具来追踪这些?
  3. 需要对我的源代码进行哪些更改才能避免这些类型的泄漏,因为它们似乎不同于 Haskell 中更常见的空间泄漏?

最佳答案

这听起来确实像是没有正确完成外部指针。这有几个可能的原因:

  1. 底层 C 库没有正确释放内存。
  2. Haskell 库没有正确设置终结。
  3. ForeignPtr 对象未被释放。

我认为实际上很有可能是选项 3。如果 RTS 在第一代 GC 中始终找到足够的内存,那么它就不会费心运行主要收集。幸运的是,这是最容易诊断的。只需让您的程序经常运行 System.Memory.performGC 即可。如果修复了它,那么您就找到了错误并可以调整您想要执行此操作的频率。

另一个可能的问题是,您可能在长生命周期的 thunk 或其他闭包中存在外部指针。确保你没有。


使用包装的 C 库时,一个特别强烈的可能性是包装函数将返回 ByteString,其底层数组由 C 代码分配。因此,您从 yaml 返回的任何 ByteString 都可能是堆外的。

关于linux - 在 GHC 的堆分析器的 View 之外可能发生哪些内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70465679/

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