我知道在C++这样的编译语言中,编译器足够聪明,可以计算出将来何时不再需要某个变量,并可以清除这些变量。
R也是这样做的吗?也就是说,它能告诉一个变量在函数的其余部分根本没有使用,并决定删除它吗?(我的意思是,当gc()
被下一次调用时,我知道R不会调用gc()
,直到它需要更多的内存。)或者如果我们有一个高内存使用的函数,需要在低规格的PC上运行,我们知道一个函数已经完成了这样一个数组,那么最好使用rm()
来删除这个数组,这样R就知道它可以在下次调用gc()
时清除内存?
或者有没有更好的方法使用带花括号的作用域来减少R中的内存使用?
1条答案
按热度按时间kxe2p93d1#
**tl;dr:**GC不向前看;仍然绑定到任何地方的名称的对象将不会被GC收集。
R GC(以及我所知道的所有其他语言中的GC)根本不查看代码。相反,GC跟踪内存引用(通过不同的机制)并在不再引用时释放内存。
此外,C++ * 也 * 不抢先清理变量;事实上,这是其形式语义的重要组成部分,许多代码都依赖于这种行为,例如
std::scoped_lock
。相反,R和C都有 * 变量作用域的概念:* 当一个名称超出作用域(即执行到达声明变量的作用域的末尾)时,它会被删除。在R的情况下,所有这一切意味着你不能再引用该变量(尽管有通过closures的转义阴影),并且变量后面的值不再被该变量引用 *(但可能来自其他地方)。一旦一个值不再被任何地方引用,它的内存可以在GC运行时被回收。
C更复杂,但简单地说:如果变量是一个左值,那么它所引用的值的生命周期就结束了。在C++中,当一个值的生命周期结束时,它的析构函数就会运行,它的内存就会被释放。
也就是说,在一个假设的语言中,GC可以查看代码,向前看,并抢先释放内存。Rust做了类似的事情来确定是否仍然使用引用(但它不使用信息来释放内存,只是为了满足borrow checker)。