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

Where does GHC allocate foreign memory and how does the garbage collector treat it?

这个问题是关于函数 alloca and malloc from Foreign.Marshal.Alloc and newForeignPtr and mallocForeignPtr from Foreign.ForeignPtr 的。分配的内存存放在哪里,垃圾收集器如何处理它?

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

alloca f 做类似的分配,用指针调用 f,然后释放内存。 f returns.

后不得使用指针

这些例程并不意味着在日常代码中使用,而只是为了与其他语言交互,使用类 C 接口 (FFI)。您将获得与 C 提供的完全相同的内存安全保证——这实际上意味着 none。因此它是相当危险的,应该小心使用。

相比之下,指向ForeignPtr的内存仍然存在于堆中,但在不再有指针(即Haskell的ForeignPtr a)引用后将被垃圾回收记忆。注意,即使这里使用了垃圾收集,这种指针也不是没有风险的。事实上,当 Haskell 不再有指向内存的活动指针时,运行时将释放它,即使该指针在外语中仍然存在。程序员必须确保这永远不会发生。

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

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

newForeignPtr 似乎与您的问题无关。

全部分配动态内存,而且在堆上。

奇数是malloc; malloc 分配的内存需要显式释放。

alloca 分配临时动态内存并将其传递给计算。当计算结束时,内存会自动释放。

mallocForeignPtr 分配内存和 returns 一个外部指针。当指针被丢弃时,内存会自动释放。

newForeignPtr 添加对现有动态分配内存的新引用。仅当对象的最后一个引用被删除时,内存才会被释放。

如果你懂C++:malloc就是裸体newmalloca就是unique_ptr/auto_ptrmallocForeignPtrnewForeignPtrshared_ptr.