6

我找不到太多关于何时适合在 Ruby 扩展中声明 a VALUEasvolatile以避免过早地对使用中的对象进行垃圾收集的文档。

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

什么时候volatile不需要使用:

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

什么volatile 时候需要使用

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

其他避免GC的方法

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

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

4

2 回答 2

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
}

您只需告诉编译器保持变量不变。不要对其进行任何优化,一些中断可能会改变它的值。在这方面它工作得很好。

于 2019-07-11T09:59:36.977 回答
0

volatile基于变量不能“自行”更改值的假设,将变量标记为可防止 C/C++ 编译器应用某些优化。维基百科:易失性变量

我认为应该在 aVALUE与 C 扩展之外的 Ruby 代码共享或可以更改时使用它,以使编译器意识到这一事实。看看这个例子

于 2013-10-12T11:33:20.117 回答