为什么Java WeakReference案例会出现OutOfMemoryError?;
我知道弱引用将很容易使用GC。及 弱引用对象,不阻止其引用对象可终结、终结和回收。弱引用通常用于实现规范化映射。 假设垃圾收集器在某个时间点确定某个对象是弱可访问的。届时,它将自动清除对该对象的所有弱引用,以及对任何其他弱可及对象的所有弱引用,通过强引用和软引用链可以从这些弱可及对象中获得该对象。同时,它将声明所有以前弱可达的对象都是可终结的。同时或在稍后的某个时间,它将使那些在引用队列中注册的新清除的弱引用排队 但是,下面的代码将用于OOM为什么Java WeakReference案例会出现OutOfMemoryError?;,java,Java,我知道弱引用将很容易使用GC。及 弱引用对象,不阻止其引用对象可终结、终结和回收。弱引用通常用于实现规范化映射。 假设垃圾收集器在某个时间点确定某个对象是弱可访问的。届时,它将自动清除对该对象的所有弱引用,以及对任何其他弱可及对象的所有弱引用,通过强引用和软引用链可以从这些弱可及对象中获得该对象。同时,它将声明所有以前弱可达的对象都是可终结的。同时或在稍后的某个时间,它将使那些在引用队列中注册的新清除的弱引用排队 但是,下面的代码将用于OOM //-XX:+HeapDumpOnOutOfMem
//-XX:+HeapDumpOnOutOfMemoryError -Xmx20m -Xms20m -XX:+PrintGCDetails
@Test(expected = OutOfMemoryError.class)
public void testOne() {
WeakReference<List<char[]>> holder = new WeakReference<>(Lists.newLinkedList());
for (int i = 0; i < 20; i++) {
holder.get().add(new char[_512_KB]);
System.out.println("i = " + i + "; size = " + holder.get().size());
}
}
GC被调用。谢谢@matt<代码>holder.get().add(新字符[_512_KB])代码>导致案例 更好的代码是:
//-XX:+HeapDumpOnOutOfMemoryError -Xmx20m -Xms20m -XX:+PrintGCDetails
@Test(expected = OutOfMemoryError.class)
public void testOne() {
WeakReference<List<char[]>> holder = new WeakReference<>(Lists.newLinkedList());
for (int i = 0; i < 20; i++) {
char[] chs = new char[_512_KB];
holder.get().add(chs);
System.out.println("i = " + i + "; size = " + holder.get().size());
}
}
/-XX:+heapdumponotofmemoryError-Xmx20m-Xms20m-XX:+PrintGCDetails
@测试(预期为OutOfMemoryError.class)
公共void testOne(){
WeakReference holder=newweakreference(Lists.newLinkedList());
对于(int i=0;i<20;i++){
char[]chs=新字符[_512_KB];
holder.get().add(chs);
System.out.println(“i=“+i+”size=“+holder.get().size());
}
}
好吧,在第一种情况下,您只有一个重复使用的弱引用,因此您填写了一个无法收集的列表(或者如果它将被收集,您将得到一个引用错误)。您的第二个案例使用了两个列表,其中一个可以在迭代过程中根据需要收集。如果您使用了两个列表,那么当您添加到其中一个列表时,内存不足,另一个可以删除。但是,如果只有一个列表,并且在添加到列表的中途,内存不足,则无法删除当前使用的列表,因为您当前正在使用它。因此,没有任何地方可以恢复内存,因此会出现内存不足错误。holder.get()
您对要调用的列表有很强的引用add
。在调用add之前,将分配新的char[]。因此,在分配更多内存时,始终有一个强引用。
//-XX:+HeapDumpOnOutOfMemoryError -Xmx20m -Xms20m -XX:+PrintGCDetails
@Test(expected = OutOfMemoryError.class)
public void testOne() {
WeakReference<List<char[]>> holder = new WeakReference<>(Lists.newLinkedList());
for (int i = 0; i < 20; i++) {
char[] chs = new char[_512_KB];
holder.get().add(chs);
System.out.println("i = " + i + "; size = " + holder.get().size());
}
}