2017-06-10 25 views
5

我有一些代码,我怀疑是内存泄漏。 作为代码使用ccall并保持内部指针, 这是为了通过代码,期间finalizer小号ccall ED被free'd保持显著信息。是否手动调用`gc()`,导致所有`finalizer`被立即执行?

在我调试我打电话gc()。 而且我想知道这是否会立即触发连接到已移出范围的所有物体的所有finalizer s

回答应该只关注julie 0.5+。

回答

4

上@以赛亚的答案(删除)的讨论后,我决定捅了一些内部人,并得到一些这方面的透明度。其结果是,我有充分根据的是,当gc()在顶层称为- 在局部范围,即没有 - 那么下面保证可以依靠:

对象是否可达,你打电话gc()它将被定稿

这是相当明确的削减。顶层的部分是显著,因为当你在一个局部范围内调用gc(),局部引用可能会或可能不会被认为是可到达,即使他们将永远不会被再次使用。

这保证不扫“可达性”的地毯下一些不确定性,因为它可能不是很明显的对象是否可达与否,因为语言运行库可能会保持到各种原因,某些对象的引用。这些原因应该被详尽记录,但目前它们不是。一对夫妇的显着的情况下运行时就会保存对象:

  • 一个单型的唯一实例是永久的,永远不会被收集或完成;

  • 方法高速缓存也是永久性的,这尤其意味着当你可能期望它们是因为方法高速缓存保持对它们被定义的模块的引用时,模块不会被释放。

在“正常情况”,然而 - 这就是我怀疑这个问题是越来越善于 - 是的,呼吁gc()当一个对象不再可达导致它被收集并“立即”完成,即在gc()呼叫返回之前。

+0

这是一个伟大的答案斯特凡。公平地说,这只适用于当前的gc()实现,而不是语言合同?即这种行为在将来可能会改变。例如,如果我们得到一个多线程gc? – aviks

+0

是的,如果我们得到并发的gc,所有的投注都关闭 - 但我们当然必须考虑这种影响。在一个并发gc中,同时运行的是增变器线程和收集器线程,所以在增变器线程中调用'gc()'还不完全清楚。它可能会被安排阻塞调用线程,直到收集线程中发生“完全收集”为止。或者它可以调用stop-the-world gc算法来代替并发收集器,但是我们有两个不同的gc实现,这很奇怪。 – StefanKarpinski