18

我已经读过很多次了,Haskell 中的惰性求值有时可能会导致空间泄漏。什么样的代码会导致空间泄漏?如何检测它们?程序员可以采取哪些预防措施来避免它们?

4

2 回答 2

12

你可能会得到很多答案,这是我在尝试做一些“现实世界”应用程序时遇到的一个。我正在使用多线程和一些 MVar 来传递数据(MVar 类似于锁定的共享内存)。我的典型模式是:

a <- takeMVar mvar
putMVar mvar (a + 1)

然后,有时,当发生适当的情况时,我会执行以下操作:

a <- takeMVar mvar
when (a > 10) ....

问题是 mvar 的内容本质上是 (0 + 1 + 1 + 1 + ....)...对于像 100k 这样的数字来说非常密集...这种类型的问题在我的代码中非常普遍;不幸的是,对于多线程应用程序来说,很容易遇到这样的问题。

检测...我所做的是以产生有关内存消耗的数据的模式启动haskell,启动和停止不同的线程并查看内存占用是否稳定...

thunk 泄漏的剖析(带有如何调试它的说明)

示例:由于 map 函数导致的 Thunk 内存泄漏

于 2011-10-14T14:57:38.193 回答
4

在对大型数据结构进行递归时,我遇到了这个问题。建立的 thunk 太多了,然后你就会得到空间泄漏。

在 Haskell 中,您需要不断意识到可能会发生空间泄漏。由于不存在迭代,因此基本上任何递归函数都有可能产生空间泄漏。

为了避免这个问题,记忆递归函数,或者用尾递归的方式重写它们。

于 2011-10-20T21:37:32.457 回答