Java-何时卸载此对象?
这是我的密码:Java-何时卸载此对象?,java,garbage-collection,linked-list,Java,Garbage Collection,Linked List,这是我的密码: LinkedList <Mono> list = new LinkedList (); list.add(new Mono (2, 2)); list.add(new Mono (1, -1)); list.remove (1); LinkedList=newLinkedList(); 增加(新单声道(2,2)); 添加(新单声道(1,-1)); 列表。删除(1); 现在,当列表中的第二项被删除时,对象是否被销毁?也就是说,它正在
LinkedList <Mono> list = new LinkedList ();
list.add(new Mono (2, 2));
list.add(new Mono (1, -1));
list.remove (1);
LinkedList=newLinkedList();
增加(新单声道(2,2));
添加(新单声道(1,-1));
列表。删除(1);
现在,当列表中的第二项被删除时,对象是否被销毁?也就是说,它正在进行垃圾收集?编辑新问题:
是的,当没有强引用剩余时,对象将有资格进行垃圾收集。然而,JVM将尝试大批量清理垃圾,因此它实际上可以在以后的任意时间被收集(或者,如果JVM在GC到达之前终止,则永远不会被收集)
旧答案:
类卸载是一个罕见的事件,通常不会及时发生(如果有的话)
特别是,即使在它符合收集条件后,它也不会与“普通”的新对象(如Mono实例)一起被收集-它通常位于一个特殊的不同池中(Oracle JVM中的PermGen)
您应该假设一旦类被加载,它将永远保持加载状态。一旦您进入容器中的web应用程序,这并不总是正确的,但是在这些环境中工作过的任何人都可以告诉您它(不)的工作情况。您的意思是卸载对象时 空列表仍然是一个列表,因此它将保留在内存中。当你离开时,它被清除: 列表=某物 这是假设您没有为列表分配任何其他内容 就类定义本身而言,它应该永远留在内存中。类定义位于永久生成中 作为旁注。此时无法对列表进行垃圾收集。因为如果清除它,您可以在之后添加内容。类“Mono”无法卸载,因为仍然存在对它的引用。列表的类型引用了它,并且列表中仍然有一个元素 我想您不是想问类是否已卸载,而是想问实例是否已“卸载”。类的每个实例、每个对象都在堆上分配。当对象不再使用时,可以回收它在堆中占用的空间。然而,这不会立即发生。我知道的所有JVM实现都使用垃圾收集器来清理内存。要真正简化这里的事情:当堆上没有更多的可用空间来创建新对象时,垃圾收集器将启动并检查堆的哪些部分仍在使用。不再使用的零件可以重新用于新对象
因此,不再使用的对象的内存只有在垃圾收集器启动时才会被回收。这是无法预测的。第二个对象在从列表中删除后,对于gargabe集合将是可省略的,因为不再有对它的引用。。因此超出了范围
希望这有助于Java中的垃圾收集通常是不确定的,因为它将在何时发生,以及当GC循环发生时,GC将驱逐哪些符合条件的对象(“空闲”) 因此,唯一可靠的规则是:
删除
将导致第二个对象新的Mono(1,-1)
符合回收条件,因为不再有任何对它的强引用(该对象不再是强可访问的)。实际的驱逐(如果发生)将在“以后某个时候”发生,甚至可能不是下一个GC周期。使用终结器(ick)会使问题进一步复杂化
请注意,对象永远不能保证是GC'ed(例如,JVM可能只是正常终止[ab]),特定GC实现的确切语义可能不同,并且仍然是一致的虚拟机——这一切归结为可达性
快乐的编码。有很多答案,下面是我的想法。想想“范围”,这是计算机语言中的一个概念,描述了何时何地可以访问指定的内存位 这是您的原始代码,并添加了您声称删除的第二个列表成员:
LinkedList <Mono> list = new LinkedList ();
list.add(new Mono (2, 2));
list.add(new Mono (1, -1));
list.remove (1);
list.remove (2);`
LinkedList=newLinkedList();
增加(新单声道(2,2));
添加(新单声道(1,-1));
列表。删除(1);
删除列表(2)`
在list.remove(2)点,仍然可以引用对象“list”。当然,它是空的,但是你可能会决定添加一个新的单声道。您可以这样做,因为“列表”仍在范围内,所以“列表”不会回收
与此相比:
{
LinkedList <Mono> list = new LinkedList ();
list.add(new Mono (2, 2));
list.add(new Mono (1, -1));
list.remove (1);
list.remove (2);`
}
{
LinkedList=newLinkedList();
增加(新单声道(2,2));
添加(新单声道(1,-1));
列表。删除(1);
删除列表(2)`
}
在右大括号之后,不能再引用“列表”。“list”是在该范围内声明的,当范围退出时,“list”与范围本身一起从命名空间中删除。在这一点上,垃圾收集可能会发生,因为没有人可能再次使用“列表”
注意你物品的范围。如果要影响垃圾收集,请将对象的范围限制在使用它们的区域内。碰巧,这也是一种很好的编程风格。我想人们会对您使用的术语感到困惑。我相信你是在问你的
Mono
对象是否会被“删除”/“垃圾回收”
让我们看看您正在调用的remove(1)
这是在java.util.LinkedList
中定义的要调用的删除函数:
public E remove(int index) {
return remove(entry(index));
}
上面的函数调用以下函数(请看我在代码中的注释):
private删除(条目E){
if(e==标题)
抛出新的NoTouchElementException();
E结果=E元素;
e、 previous.next=e.next;//前面的元素现在指的是e后面的元素
private E remove(Entry<E> e) {
if (e == header)
throw new NoSuchElementException();
E result = e.element;
e.previous.next = e.next; //Preceding element refers now to the one after the element to be removed;
e.next.previous = e.previous; //Next element refers now to the one before the one to be removed;
e.next = e.previous = null; //Element to be removed doesn't refer to anything anymore;
e.element = null;
size--;
modCount++;
return result;
}