Ale*_*yMK 148 java garbage-collection
根据我的理解,如果没有其他东西"指向"该对象,Java中的垃圾收集会清除一些对象.
我的问题是,如果我们有这样的事情会发生什么:
class Node {
public object value;
public Node next;
public Node(object o, Node n) { value = 0; next = n;}
}
//...some code
{
Node a = new Node("a", null),
b = new Node("b", a),
c = new Node("c", b);
a.next = c;
} //end of scope
//...other code
Run Code Online (Sandbox Code Playgroud)
a,b和c应该是垃圾收集,但它们都被其他对象引用.
Java垃圾收集如何处理这个问题?(或者它只是一个内存消耗?)
Bil*_*ard 148
Java的GC认为对象是"垃圾",如果它们无法通过从垃圾收集根开始的链到达,那么这些对象将被收集.尽管物体可以指向彼此形成一个循环,但如果它们从根部切断,它们仍然是垃圾.
请参阅附录A中的无法访问对象部分:Java平台性能中关于垃圾收集的真相:血腥细节的策略和策略.
Ani*_*kur 124
是Java垃圾收集器处理循环引用!
How?
Run Code Online (Sandbox Code Playgroud)
有一些称为垃圾收集根(GC根)的特殊对象.它们总是可以访问的,任何拥有它们的对象也是如此.
一个简单的Java应用程序具有以下GC根源:

为了确定哪些对象不再使用,JVM间歇性地运行非常适合称为标记和扫描算法的对象.它的工作原理如下
因此,如果无法从GC根目录访问任何对象(即使它是自引用或循环引用),它将进行垃圾收集.
当然,如果程序员忘记取消引用某个对象,有时会导致内存泄漏.

来源:Java内存管理
Jer*_*fin 11
垃圾收集器从一些始终被视为"可访问"的"根"位置开始,例如CPU寄存器,堆栈和全局变量.它的工作原理是找到这些区域中的任何指针,并递归地找到它们指向的所有内容.一旦发现了这一切,其他一切都是垃圾.
当然,有很多变化,主要是为了速度.例如,大多数现代垃圾收集器都是"世代"的,意味着它们将对象分成几代,随着对象变老,垃圾收集器在它试图弄清楚该对象是否仍然有效的时间之间变得越来越长. - 它只是开始假设如果它已经存在了很长时间,那么它很可能继续存活更长时间.
尽管如此,基本思想仍然是相同的:它都是基于从一些根本开始的东西开始,它仍然可以使用它,然后追逐所有指针以找到其他可能正在使用的东西.
有趣的是:人们常常会对垃圾收集器的这一部分与远程过程调用之类的对象的编组代码之间的相似程度感到惊讶.在每种情况下,你都是从一些根对象开始,并追逐指针来找到那些引用的所有其他对象......
Jör*_*tag 10
你是对的.您描述的垃圾收集的具体形式称为" 引用计数 ".它的工作方式(从概念上讲,至少,大多数现代的引用计数实现实际上以不同的方式实现)在最简单的情况下,如下所示:
这个简单的策略确实存在你所描述的问题:如果A引用B和B引用A,那么它们的引用计数都不能小于1,这意味着它们永远不会被收集.
有四种方法可以解决这个问题:
顺便说一句,实现垃圾收集器的另一种主要方式(我已经多次暗示过这一点)正在追踪.跟踪收集器基于可达性的概念.你可以从一些你知道总是可以访问的根集开始(例如全局常量,或类,当前词法范围,当前堆栈框架),然后从那里跟踪可从根集中访问的所有对象,然后从根集可以访问的对象可以访问的所有对象,依此类推,直到你有传递闭包.那个封闭中没有的东西就是垃圾.Object
由于循环只能在其自身内访问,但无法从根集中访问,因此将收集该循环.
Java GC实际上并不像您描述的那样运行.更准确地说,它们从一组基础对象开始,通常称为"GC根",并将收集从根无法到达的任何对象.
GC根包括以下内容:
因此,在您的情况下,一旦局部变量a,b和c超出了方法末尾的范围,就不会有更多的GC根直接或间接地包含对任何三个节点的引用,并且他们将有资格进行垃圾收集.
如果你需要,TofuBeer的链接有更多细节.
| 归档时间: |
|
| 查看次数: |
48289 次 |
| 最近记录: |