关于WeakReference的回收问题

ren_xu123 2010-09-14 11:12:05
这是一段测试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);
}
}
}
...全文
380 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
ren_xu123 2010-09-18
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 ticmy 的回复:]

需要注意到的是,调用gc(),只是建议垃圾回收,并不是调用垃圾回收哦,也就是说,垃圾回收发生与否是不确定的
[/Quote]
倒………………看来用Java来控制机器的行为真是很费劲啊?
龙四 2010-09-18
  • 打赏
  • 举报
回复
需要注意到的是,调用gc(),只是建议垃圾回收,并不是调用垃圾回收哦,也就是说,垃圾回收发生与否是不确定的
ren_xu123 2010-09-18
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 wendli2008 的回复:]

不知道lz怎么测的,我用JCONSOLE测试时明显做了GC,回收了memory啊。
[/Quote]
不好意思,没用过,想请教下JConsole可以测出来为什么Debuge测不出来?
wendli2008 2010-09-17
  • 打赏
  • 举报
回复
不知道lz怎么测的,我用JCONSOLE测试时明显做了GC,回收了memory啊。
ren_xu123 2010-09-17
  • 打赏
  • 举报
回复
期待大师阿!
clariones 2010-09-15
  • 打赏
  • 举报
回复
会不会是因为debug的时候,有些调试器还在引用这些变量,所以gc的时候放不掉?
搜了一下Java debug的实现原理,也没看到啥明确的说明
坐等高手!
ren_xu123 2010-09-15
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 clariones 的回复:]

话说,
ml=null; <==== NULL了啊!
System.gc();
//按理说现在的内存中还和ml被填满之前一样,可以继续构造出这么多对象,可是,系统仍然崩溃了!
System.out.println();
for(int i=0;i<4;i++){
WeakTest.MyObject m=new WeakTest.MyObject();
Syste……
[/Quote]
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()后,内存仍然没有还是那么多!
ren_xu123 2010-09-15
  • 打赏
  • 举报
回复
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()后,内存仍然没有还是那么多!
ren_xu123 2010-09-15
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 clariones 的回复:]

会不会是因为debug的时候,有些调试器还在引用这些变量,所以gc的时候放不掉?
搜了一下Java debug的实现原理,也没看到啥明确的说明
坐等高手!
[/Quote]
我感觉如果调试的时候不能看到运行时的真实过程,那么调试会失去实际的意义。
坐等,共同进步!
clariones 2010-09-14
  • 打赏
  • 举报
回复
话说,
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); <======还往里加,当然异常了
michaellufhl 2010-09-14
  • 打赏
  • 举报
回复
看您代码的意图是应该往容器里面加:ml.add(new WeakReference(m)); 而不是把容器WeakReference起来。

当然ml=null; 导致了NPE。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧