1

有时您可能需要在不用于对象存储的扩展中分配内存——也许您有一个用于 Bloom 过滤器、图像或一大堆 Ruby 不直接使用的小结构的巨大位图。要正确使用垃圾收集器,您应该使用以下内存分配例程。这些例程比标准 malloc 函数做更多的工作。例如,如果 ALLOC_N 确定它无法分配所需的内存量,它将调用垃圾收集器来尝试回收一些空间。如果不能或请求的内存量无效,它将引发 NoMemError

但是在给定的函数中,我确切地知道何时释放内存。在这种情况下,我还应该使用ALLOC_N分配内存吗?

是否存在我应该自己释放内存的合法案例,或者最好总是使用ALLOC_N它而不关心它?

4

2 回答 2

3

ALLOC_N不会释放您分配的内存。如果它在第一次尝试分配内存时失败,它将触发 GC 以尝试释放更多内存,然后重试。

您仍然应该释放由ALLOC_N. 但是使用xfree而不是- 不幸的是,在http://www.ruby-doc.org/docs/ProgrammingRuby/html/ext_ruby.htmlfree等指南中并没有很好地描述它,但是您发现它在 Ruby 源代码和源代码中使用其他 Ruby C 扩展。

于 2013-05-09T09:50:14.670 回答
1

您可能应该使用ALLOC_N动态管理内存分配,其中您的 C 代码需要独立于对象数据存储内容,并且存储的数据需要在多个方法调用中持续存在(因此您不能确定特定 C 函数中的释放会叫做)。

如果您只是在一个复杂方法调用的上下文中创建然后丢弃它,那么您可以使用纯 C 方法进行内存管理。C 堆栈适用于真正的基础知识 例如,只需声明int foo[1000];并且您可以在内部使用该数组,C 将使用堆栈并正常清理 - Ruby 当然无法访问这些数据,除非您将其复制到最后. 但是不要过度使用它,int foo[1000000];可能会破坏堆栈并导致段错误。

该文档暗示了另一个使用原因ALLOC_N- 您将避免由于调用垃圾收集而导致的一些内存不足的情况。此外,如果您确实内存不足(与您的 C 例程所做的任何事情相反),您将获得稍微友好的 Ruby 管理的进程失败。

于 2013-05-07T09:37:36.617 回答