来自the pickaxe:
有时您可能需要在扩展中分配内存 用于对象存储 - 也许你有一个Bloom的巨大位图 过滤器,图像,或者Ruby的一大堆小结构 不直接使用。要与垃圾收集器一起正常工作, 您应该使用以下内存分配例程。这些 例程比st andard malloc函数做了更多的工作。 例如,如果ALLOC_N确定它无法分配 所需的内存量,它会调用垃圾收集器来尝试 收回一些空间。如果它不能或如果,它将引发NoMemError 请求的内存量无效
但是在给定的函数中,我确切地知道何时释放内存。在这种情况下,我是否仍应使用ALLOC_N
来分配内存?
在我应该自己释放内存时是否存在合法情况,或者最好总是使用ALLOC_N
并且不关心它?
答案 0 :(得分:3)
ALLOC_N
不会释放您分配的内存。如果在第一次尝试分配内存时失败,它将触发GC以尝试释放更多内存,然后再试一次。
您仍应释放ALLOC_N
分配的内存。但是使用xfree
而不是free
- 这在http://www.ruby-doc.org/docs/ProgrammingRuby/html/ext_ruby.html等指南中不太好描述,但是你发现它在Ruby源代码和其他Ruby C Extensions的源代码中使用。
答案 1 :(得分:1)
您可能应该使用ALLOC_N
动态管理内存分配,其中C代码需要独立于对象数据存储内容,并且存储的数据需要在多个方法调用上持久存在(因此您不能确定将调用特定C函数中的解除分配)。
如果你只是在一个复杂的方法调用的上下文中创建一些东西然后扔掉它,那么你就可以使用普通的C方法进行内存管理。 C堆栈适用于真正的基础知识。只需声明int foo[1000];
并且您可以在内部使用该数组,C将使用堆栈并正常清理 - Ruby当然无法访问此数据,除非您将其复制到最后。不要过度使用它,int foo[1000000];
可能会导致堆栈崩溃并导致段错误。
文档暗示了使用ALLOC_N
的另一个原因 - 由于调用垃圾回收,您将避免某些内存不足的情况。此外,如果你真的没有内存(而不是你的C例程会做什么),你会得到一个稍微友好的Ruby管理的进程失败。