这是一段测试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);
}
}
}

解决方案 »

  1.   

    话说,
    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);          <======还往里加,当然异常了
      

  2.   

    看您代码的意图是应该往容器里面加:ml.add(new WeakReference(m)); 而不是把容器WeakReference起来。当然ml=null; 导致了NPE。
      

  3.   

    import java.util.*;
    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()后,内存仍然没有还是那么多!
      

  4.   

    import java.util.*;
    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()后,内存仍然没有还是那么多!
      

  5.   

    会不会是因为debug的时候,有些调试器还在引用这些变量,所以gc的时候放不掉?
    搜了一下Java debug的实现原理,也没看到啥明确的说明
    坐等高手!
      

  6.   

    不知道lz怎么测的,我用JCONSOLE测试时明显做了GC,回收了memory啊。
      

  7.   

    不好意思,没用过,想请教下JConsole可以测出来为什么Debuge测不出来?
      

  8.   

    倒………………看来用Java来控制机器的行为真是很费劲啊?