日期:2014-05-20  浏览次数:20762 次

熟悉垃圾回收机制的朋友进来看看这是为什么
要点:要为每一个图片资源声明一个对象变量
  假设在一个程序声明了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对象的回收工作,从而造成内存回收不干净,为什么会不干净

------解决方案--------------------
LZ研究好深入,不知LZ看的哪本书,我也去学习下.
------解决方案--------------------
〉因为这样做会影响垃圾收集器对pic1,pic2对象的回收工作,从而造成内存回收不干净

lz要明白,垃圾回收的对象是堆内存
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,再让它们指向新的对象好一点吧。
------解决方案--------------------
据说老版本的JAVA对内存进行回收的方式是,当发现一块内存区域在程序中被对象引用的次数为0时,就进行回收。但是这样做可能会产生一些问题,比如用户不希望释放的空间被垃圾收集器自行释放。因此后来对回收机制进行了修改,更加具体的细节我也不清楚了。

如LZ所写的“不可这样做”,程序会丢失对pic1和pic2的引用,此时垃圾收集器不会自动回收这两块区域,成程序员又无法自行释放,这样就可能导致内存回收不干净。

嗯,第二段是我猜测的。
------解决方案--------------------
同意以上各位的观点,LZ可能看的书有点误人子弟。
------解决方案--------------------
其实楼住的这本书写的还不错,能指出这个问题,但是作者并没有说明这个问题
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虚拟机回收不了原来最早申请的内存了。




------解决方案--------------------
好深
------解决方案--------------------
探讨
其实楼住的这本书写的还不错,能指出这个问题,但是作者并没有说明这个问题
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虚拟机回收不了原来最早申请的内存了。

------解决方案--------------------
ThirstyCrow
不是我扯蛋,事实就是这样。你自己不懂而已
java的地层是C++做的,既然是C++ 做的就会在使用不当的时候
有内存泄露,
ThirstyCrow 不懂就不要乱否定别人的成果,如果你能写JNI ,能够直接
用C++ 操作虚拟机并且能释放虚拟机的内存,能够自己做个内存泄露检测工具
你就能解释楼住的这个问题

------解决方案--------------------
楼上的观点确实有问题啊.

垃圾回收器,做的就是回收那些没有引用指向的对象,虽然它的工作方式不尽如人意,成为垃圾的对象,不能叫内存泄露,因为这此垃圾都记录在案了,都可以找得到。

回到pic1,pic2的问题上,如果pic1,pic2指向的对象没有用了,还让pic1和pic2指着,对象占的内存永远也不可能释放,这和内存泄漏一样了。
------解决方案--------------------