这是一段测试WeakReference的回收的代码,可惜失败了。
是否有高手能解释这个问题,顺便类比着这个类给我讲一下SoftReference和PhantomReference的回收问题。import java.util.*;
import java.lang.ref.*;
public class WeakTest {
//尽量大的一个数,尽量占用内存
static int VeryBig=1000000;
//配合VeryBig,尽量吃掉内存
static int MostLength=4;
private static class MyObject{
long[] l;
public MyObject(){
l=new long[VeryBig];
}
}
public static void main(String arg[]){
//尽量使用内存
ArrayList ml=new ArrayList();
for(int i=0;i<MostLength;i++){
WeakTest.MyObject m=new WeakTest.MyObject();
System.out.println(i);
ml.add(m);
}
//用WeakReference注册到ReferenceQueue中,然后置空ml,再执行System.gc()
ReferenceQueue rq=new ReferenceQueue();
WeakReference wr=new WeakReference(ml,rq);
ml=null;
System.gc();
//按理说现在的内存中还和ml被填满之前一样,可以继续构造出这么多对象,可是,系统仍然崩溃了!
System.out.println();
for(int i=0;i<4;i++){
WeakTest.MyObject m=new WeakTest.MyObject();
System.out.println(i);
ml.add(m);
}
}
}
是否有高手能解释这个问题,顺便类比着这个类给我讲一下SoftReference和PhantomReference的回收问题。import java.util.*;
import java.lang.ref.*;
public class WeakTest {
//尽量大的一个数,尽量占用内存
static int VeryBig=1000000;
//配合VeryBig,尽量吃掉内存
static int MostLength=4;
private static class MyObject{
long[] l;
public MyObject(){
l=new long[VeryBig];
}
}
public static void main(String arg[]){
//尽量使用内存
ArrayList ml=new ArrayList();
for(int i=0;i<MostLength;i++){
WeakTest.MyObject m=new WeakTest.MyObject();
System.out.println(i);
ml.add(m);
}
//用WeakReference注册到ReferenceQueue中,然后置空ml,再执行System.gc()
ReferenceQueue rq=new ReferenceQueue();
WeakReference wr=new WeakReference(ml,rq);
ml=null;
System.gc();
//按理说现在的内存中还和ml被填满之前一样,可以继续构造出这么多对象,可是,系统仍然崩溃了!
System.out.println();
for(int i=0;i<4;i++){
WeakTest.MyObject m=new WeakTest.MyObject();
System.out.println(i);
ml.add(m);
}
}
}
ml=null; <==== NULL了啊!
System.gc();
//按理说现在的内存中还和ml被填满之前一样,可以继续构造出这么多对象,可是,系统仍然崩溃了!
System.out.println();
for(int i=0;i<4;i++){
WeakTest.MyObject m=new WeakTest.MyObject();
System.out.println(i);
ml.add(m); <======还往里加,当然异常了
import java.lang.ref.*;
public class WeakTest {
//尽量大的一个数,尽量占用内存
static int VeryBig=1000000;
//配合VeryBig,尽量吃掉内存
static int MostLength=7;
private static class MyObject{
long[] l;
public MyObject(){
l=new long[VeryBig];
}
}
public static void main(String arg[]){
//尽量使用内存
ArrayList ml=new ArrayList();
for(int i=0;i<MostLength;i++){
WeakTest.MyObject m=new WeakTest.MyObject();
System.out.println(i);
ml.add(m);
}
//用WeakReference注册到ReferenceQueue中,然后置空ml,再执行System.gc()
ReferenceQueue rq=new ReferenceQueue();
WeakReference wr=new WeakReference(ml,rq);
ml=null;
System.gc();
//按理说现在的内存中还和ml被填满之前一样,可以继续构造出这么多对象,可是,系统仍然崩溃了!
ml=new ArrayList(); System.out.println();
for(int i=0;i<MostLength;i++){
WeakTest.MyObject m=new WeakTest.MyObject();
System.out.println(i);
ml.add(m);
}
}
}不好意思,犯了点错误,这下代码改了,能跑了,可是发现另一个问题。当我运行的时候,没问题,这个程序可以运行,可当我单步调(同时打开任务管理器,查看内存使用情况)的时候,内存还是爆了,而且gc()后,内存仍然没有还是那么多!
import java.lang.ref.*;
public class WeakTest {
//尽量大的一个数,尽量占用内存
static int VeryBig=1000000;
//配合VeryBig,尽量吃掉内存
static int MostLength=7;
private static class MyObject{
long[] l;
public MyObject(){
l=new long[VeryBig];
}
}
public static void main(String arg[]){
//尽量使用内存
ArrayList ml=new ArrayList();
for(int i=0;i<MostLength;i++){
WeakTest.MyObject m=new WeakTest.MyObject();
System.out.println(i);
ml.add(m);
}
//用WeakReference注册到ReferenceQueue中,然后置空ml,再执行System.gc()
ReferenceQueue rq=new ReferenceQueue();
WeakReference wr=new WeakReference(ml,rq);
ml=null;
System.gc();
//按理说现在的内存中还和ml被填满之前一样,可以继续构造出这么多对象,可是,系统仍然崩溃了!
ml=new ArrayList();System.out.println();
for(int i=0;i<MostLength;i++){
WeakTest.MyObject m=new WeakTest.MyObject();
System.out.println(i);
ml.add(m);
}
}
}不好意思,犯了点错误,这下代码改了,能跑了,可是发现另一个问题。当我运行的时候,没问题,这个程序可以运行,可当我单步调(同时打开任务管理器,查看内存使用情况)的时候,内存还是爆了,而且gc()后,内存仍然没有还是那么多!
搜了一下Java debug的实现原理,也没看到啥明确的说明
坐等高手!