什么时候需要在Ruby C扩展中声明不稳定的VALUE?

时间:2013-10-03 21:38:39

标签: c++ c ruby garbage-collection mark-and-sweep

我找不到很多关于何时在Ruby扩展中将VALUE声明为volatile以避免在使用对象过早垃圾收集的文档。

这是我到目前为止所学到的。任何人都可以填补空白吗?

volatile需要 时,

  • 在C ++对象成员中(因为它们从不在堆栈中?
  • 在不调用Ruby API的C / C ++方法中(因为在调用Ruby API之前GC没有打开

volatile 需要

  • 在C / C ++方法中调用任何Ruby ALLOCmalloc宏/函数(因为这些可以在内存高度碎片化时触发GC
  • 在调用任何Ruby函数的C / C ++方法中(例如rb_funcallrb_ary_new等)

其他避免GC的方法

  • 标记正在使用的VALUE
  • 在对象创建期间禁用GC,然后重新启用它
  • 不要使用Ruby的分配方法(冒险)

一切都正确吗?我错过了什么细节?除了标记,volatile是唯一的方法吗?

2 个答案:

答案 0 :(得分:1)

我想说,根据经验,您可以在运行时随时更改您的变量值,并且不知道何时使用关键字volatile。这包括中断。例如,您具有中断回调函数,该函数可计算用户按下键盘上的某些内容的次数。您的程序不知道用户何时按下键盘上的按钮,因此必须使用volatile关键字声明您的计数器变量。

如前所述,它禁用了针对变量的某些编译器优化。例如:

int a = 5;
while(a == 5){
  //do something
}

编译器将while(a == 5)语句优化为while(true),因为它看到变量a在运行时不能更改,并且没有用处检查每个循环的a的值。因此,您最终陷入无限循环。但是,如果您添加关键字volatile

volatile int a = 5;
while(a == 5){
  //do something
}

您只是告诉编译器将变量保留为原样。请勿对其进行任何优化,某些中断可能会更改其值。在这个上它很好用。

答案 1 :(得分:0)

将变量标记为volatile会阻止C / C ++编译器应用某些优化,这是基于变量不能“自行”更改值的假设。 Wikipedia: Volatile variable

我认为应该在与VALUE共享时使用,或者可以通过C扩展外部的Ruby代码进行更改,以使编译器意识到这一事实。看看this example