读书人

熟悉垃圾回收机制的朋友进来看看这是为

发布时间: 2011-12-29 22:09:38 作者: rapoo

熟悉垃圾回收机制的朋友进来看看这是为什么
要点:要为每一个图片资源声明一个对象变量
  假设在一个程序声明了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指着,对象占的内存永远也不可能释放,这和内存泄漏一样了。
------解决方案--------------------


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

[解决办法]
探讨
引用:
回到pic1,pic2的问题上,如果pic1,pic2指向的对象没有用了,还让pic1和pic2指着,对象占的内存永远也不可能释放,这和内存泄漏一样了。

不是这样的,即使你不让pic1=null;jvm也能确定在代码最后一次对pic1进行使用之后将它看做垃圾,编译器可以进行活性分析确定其生命周期的终结,并不需要你手工的设置null来告诉jvm。不会出现“对象占的内存永远不可能释放”这种问题。
可以参考
http://developers.sun.com/learning/javaoneonline/2007/pdf/TS-2906.pdf
或者
http://blog.csdn.net/axman/archive/2009/04/09/4058542.aspx


[解决办法]
讨论变得越来越精彩
学习ing
[解决办法]
探讨
引用:
回到pic1,pic2的问题上,如果pic1,pic2指向的对象没有用了,还让pic1和pic2指着,对象占的内存永远也不可能释放,这和内存泄漏一样了。

不是这样的,即使你不让pic1=null;jvm也能确定在代码最后一次对pic1进行使用之后将它看做垃圾,编译器可以进行活性分析确定其生命周期的终结,并不需要你手工的设置null来告诉jvm。不会出现“对象占的内存永远不可能释放”这种问题。
可以参考
http://developers.sun.com/learning/javaoneonline/2007/pdf/TS-2906.pdf
或者
http://blog.csdn.net/axman/archive/2009/04/09/4058542.aspx

读书人网 >J2SE开发

热点推荐