要点:要为每一个图片资源声明一个对象变量
假设在一个程序声明了2个图片对象:
Image pic1,pic2;
如果在某一时刻要使用pic1和pic2则:
if(pic1==null)pic1=Image.createImage("/1.png");
if(pic2==null)pic2=Image.createImage("/2.png");
当这些图片用完后,就应当:
pic1=null;
pic2=null;
如果需要使用另外两个图片3.png和4.png,则最好另声明两个变量对象pic3,pic4来导入它们,不要使用pic1,pic2变量来导入这两个图片,如:
if(pic1==null)pic1=Image.createImage("/3.png");//不要这样做,为什么不要这样做
if(pic2==null)pic2=Image.createImage("/4.png");//不要这样做,为什么不要这样做
因为这样做会影响垃圾收集器对pic1,pic2对象的回收工作,从而造成内存回收不干净,为什么会不干净
假设在一个程序声明了2个图片对象:
Image pic1,pic2;
如果在某一时刻要使用pic1和pic2则:
if(pic1==null)pic1=Image.createImage("/1.png");
if(pic2==null)pic2=Image.createImage("/2.png");
当这些图片用完后,就应当:
pic1=null;
pic2=null;
如果需要使用另外两个图片3.png和4.png,则最好另声明两个变量对象pic3,pic4来导入它们,不要使用pic1,pic2变量来导入这两个图片,如:
if(pic1==null)pic1=Image.createImage("/3.png");//不要这样做,为什么不要这样做
if(pic2==null)pic2=Image.createImage("/4.png");//不要这样做,为什么不要这样做
因为这样做会影响垃圾收集器对pic1,pic2对象的回收工作,从而造成内存回收不干净,为什么会不干净
解决方案 »
- Java版另类 Hello World
- 求救:字符串分割问题,头疼
- 我的linux不认识全角下的"-",怎么办
- dom4j解析问题!(牛人帮忙啊 !在线等!)selectSingleNode报错!
- 能否设置eclipse在不同的workspace下开启或禁用某些插件?
- 输入流对象中的mark()方法的参数有何作用?
- 急:哪位有把Unicode转化成GB的源码?
- 在java中怎样实现将主机字节顺序转换成网络字节顺序
- 我用javamail接收21cn的邮件,为什么发信人姓名总是乱码。。。。。
- JVM占用内存平稳但系统内存一直在增加直到耗尽
- JAVA 有规则的不重复排列 请教各位。?
- ResultSet转DefaultTableModel的字段类型问题,目前并未找到特别好的解决方案,欢迎大家来讨论一下
Image pic1,pic2;
你pic1,pic2是放在栈内存里的
所以,pic1,pic2不属于回收的对象
pic1=null;
pic2=null;
如果需要使用另外两个图片3.png和4.png,则最好另声明两个变量对象pic3,pic4来导入它们,不要使用pic1,pic2变量来导入这两个图片,如:
if(pic1==null)pic1=Image.createImage("/3.png");//不要这样做,为什么不要这样做
if(pic2==null)pic2=Image.createImage("/4.png");//不要这样做,为什么不要这样做
我认为这段话的观点有问题.
用新的pic3,pic4倒是不给垃圾回收添加麻烦,但pic1和pic2指向听对象没有用了,还占着内存,确会给你的程序带来麻烦。相较而言,还是把pic1,pic2设为null,再让它们指向新的对象好一点吧。
pic1现在指向了一个新的对象,不指向原来那个了,难道它不会回收原来那个对象吗
所以说
当执行
pic1=null;
pic2=null;
的时候,他们原本指向堆内存的那个对象会被回收
而pic1,pic2不会
所以,没有必要再弄个pic3,pic4出来
直接再用pic1,pic2就好了
if(pic1==null)pic1=Image.createImage("/3.png");//不要这样做,为什么不要这样做
if(pic2==null)pic2=Image.createImage("/4.png");//不要这样做,为什么不要这样做
为什么不要这样做呢,因为这样会导致内存泄露。
pic1 =null pic2=null 指示JAVA虚拟机可以回收 pic1 和 pic2 在堆上申请的内存
但是pic1 和 pic2 此时所指向的堆上的内存并没有释放,因为在等JAVA虚拟机空闲的时候再回收内存。 然而此时又重新在堆上申请内存然后赋值给 pic1 和pic2 。 现在问题就出现了。那么原来的那片申请的空间变成了一个野地址,即没有变量指向它了,所以JAVA虚拟机回收不了原来最早申请的内存了。
不是我扯蛋,事实就是这样。你自己不懂而已
java的地层是C++做的,既然是C++ 做的就会在使用不当的时候
有内存泄露,
ThirstyCrow 不懂就不要乱否定别人的成果,如果你能写JNI ,能够直接
用C++ 操作虚拟机并且能释放虚拟机的内存,能够自己做个内存泄露检测工具
你就能解释楼住的这个问题
可以参考
http://developers.sun.com/learning/javaoneonline/2007/pdf/TS-2906.pdf
或者
http://blog.csdn.net/axman/archive/2009/04/09/4058542.aspx
学习ing
import java.io.IOException;public class Main { public static void main(String[] args) throws IOException { int[] arr1 = new int[Short.MAX_VALUE];
int[] arr2 = new int[Short.MAX_VALUE]; System.out.println("Press any key to continue.");
System.in.read();
// 启动jvisualvm, 对本地的Main程序进行heap dump,
// 查看所有int[]对象,你会看到两个大小为131084的
// 实例。这里所说的大小是只对象所占空间的大小,而
// 不是数组的长度。用鼠标选择这两个对象,可以看到它
// 们的长度为32767。
arr2 = new int[0];
System.out.println("Press any key to continue.");
System.in.read();
// 重新进行heap dump,这次只乘下一个大小为131084的
// int[]对象。arr2最初指向的对象,已经可以被回收了,
// 所以不再列出。
printArray(arr1); // 现在arr1使用完了,再次进行heap dump,还是能看到
// 大小为131084的int[]对象。即使你点Monitor tab下
// 的Perform GC强制回收,结果仍是如此。这说明arr1指
// 向的int[]对象暂时是不能回收的。或者还有其它解释?
// (比如说JDK自带的JRE没有启用JIT?)
System.out.println("Press any key to continue.");
System.in.read();
} public static void printArray(int[] arr) {
return;
}
}
private String s1;
public Test(String str){
this.s1 = str;
System.err.println("创建对象:"+s1);
}
public static void main(String[] args){
Test t1 = new Test("t1");
Test t2 = new Test("t2");
for(int i = 0;i<100000;i++){
}
System.err.println("准备调用System.gc()!");
System.gc();
System.err.println("调用System.gc()之后!");
System.err.println("让t1指向新的对象,内容为t3");
t1 = new Test("t3");
System.err.println("准备再次调用System.gc()!");
System.gc();
System.err.println("再次调用System.gc()之后!");
}
public void finalize(){
System.err.println("Garbage collection!I'm "+s1);
}
}
多运行几次,因为多次运行的结果可能不同。
但起码有情况能说明,t2可能会在t3创建之前就回收了。上面链接中那个报告是gc 技术组给出的,估计可信性比较大。
使用完了只是你自己的认为而已,但事实上arr1还指向原来那个对象
不过你对java的内存回收机制似乎是不太了解,这个跟C++是不是使用恰当倒是没多大关系。
至于那本书上说,不要那样使用,会造成回收不干净那完全是扯淡,如果那样回收不干净,你用其它方式同样回收不干净,其它方式能回收,那样也能回收。这取决与jvm实现,而且没有任何一个官方文档与java编程规范中说这样用不好,会回收不干净,如果那个虚拟机连这种回收都做不到,那么那个虚拟机不用也罢。