GHC在哪里分配外国内存以及垃圾收集器如何处理它?

时间:2016-07-13 10:36:38

标签: haskell memory-management garbage-collection ghc

此问题与alloca中的mallocForeign.Marshal.Alloc以及newForeignPtr中的mallocForeignPtrForeign.ForeignPtr中的函数有关。分配的内存在哪里存在以及垃圾收集器如何处理它?<​​/ p>

3 个答案:

答案 0 :(得分:6)

Ptr a分配的malloc指向的内存存在于堆上,就像在C编程语言中一样。它被垃圾收集器忽略 - 你必须使用free自己手动解除分配,并且在此之后再小心不要再使用它。

alloca f执行类似的分配,使用指针调用f,然后释放内存。 <{1}}返回后,不得使用指针。

这些例程不是用于日常代码,而是仅用于与其他语言的接口,使用类似C的接口(FFI)。您可以获得C提供的完全相同的内存安全保障 - 这几乎意味着没有。因此它非常危险,应该非常谨慎地使用。

相比之下,f指向的内存仍然存在于堆上,但在没有更多指针(即Haskell的ForeignPtr)引用内存之后将被垃圾收集。请注意,即使在这里使用垃圾收集,这种指针也没有风险。实际上,当Haskell没有更多关于内存的实时指针时,运行时将释放它,即使该指针仍然存在于外语中。程序员必须确保永远不会发生这种情况。

答案 1 :(得分:3)

malloc调用C malloc(),因此它在C堆上分配内存,您必须手动释放。 (如果您愿意,也可以使用free()从C中执行此操作。)

allocamallocForeignPtr分配固定字节数组,它们存在于Haskell固定堆上。 GC将在不再需要时自动释放它们,但永远不会移动它们(因为它们被固定),因此您可以将它们的地址传递给C函数。

newForeignPtr似乎与您的问题无关。

答案 2 :(得分:1)

所有分配动态内存并且它在堆上。

奇怪的是malloc;由malloc分配的内存需要明确释放。

alloca分配临时动态内存并将其传递给计算。计算结束后,内存会自动解除分配。

mallocForeignPtr分配内存并返回外部指针。当指针被丢弃时,内存会自动释放。

newForeignPtr添加对现有动态分配内存的新引用。只有在删除对象的LAST引用时才会释放内存。

如果您了解C ++:malloc是裸newmallocaunique_ptr/auto_ptrmallocForeignPtrnewForeignPtrshared_ptr