Java—关于垃圾收集

           创建对象会占据内存,如果程序执行流程中已无法再使用某个对象,该对象就只是徒耗内存的垃圾

          对于不再有用的对象,JVM有垃圾收集机制(GC),收集到的垃圾对象所占据的内存空间,会被垃圾收集器释放。那么,哪些会被JVM认定为垃圾对象?简单地说,无法通过变量参考的对象,就是GC认定的垃圾对象。

          在学习GC之前,你首先应该记住一个单词:“stop-the-world”。Stop-the-world会在任何一种GC算法中发生。Stop-the-world意味着 JVM 因为要执行GC而停止了应用程序的执行。当Stop-the-world发生时,除了GC所需的线程以外,所有线程都处于等待状态,直到GC任务完成。GC优化很多时候就是指减少Stop-the-world发生的时间。

           

        Java的GC机制是自动进行的,和c语言有些区别需要程序员自己保证内存的使用和回收。

       Java的内存分配和回收也主要在Java的堆上进行的,Java的堆中存储了大量的对象实例,所以Java的堆也叫GC堆。

       Java在垃圾收集的过程中,主要用到了分代收集算法

        

     1、 假设有一个类:

          public class Some{

              Some next;

           }


          若是从程序进入点开始,有段代码如下:

          Some   some1 = new Some();

          Some   some2 =  new Some();

          Some   some1 = some2 ;


         执行到第二行是,主线程可以通过参考名称所参考到的对象,如图6.20所示。

                           

                       

         执行到第三行时,是将some2参考的对象给some1参考,如图6.21所示。

                           

           原先some1参考的对象不再被任何名称参考,通过主线程也不再能参考到该对象,这个对象就是内存中的垃圾,GC会自动找出这些垃圾并给予回收。

          GC的基本概念就是这样,但可以加以变化。如果有段程序是这样:

                       Some    some   = new  Some();

                        some.next = new Some();

                        some  = null;

            在执行到第二行是,情况如图6.22所示,此时还没有对象是垃圾。

                         

               由于从主流程开始,可以通过some参考至中间的对象,而some.next可以参考至右边的对象,目前没有必要回收任何对象。执行完成第三行后,情况编程如图6.23所示。                   


            由于从主流程开始,无法通过some参考至中间对象,也就无法再通过中间对象的next参考至右边对象,所以两个对象都是垃圾。同样的道理,下面程序代码中,数组参考到的对象全部都会被回收,如图6.24所示。

                Some[] somes = {new Some(),new Some(),new Some};

                somes =  null;

                


              被回收的对象包括了数组对象本身,以及三个索引所参考的三个对象。如果是形同孤岛的对象,例如

                   Some some = new Some();

                   some.next = new Some();

                   some.next.next   =  new Some();

                   some.next.next.next  =  some;

                   some =  null;

            执行到第四行时,情况如图6.25所示。

                   

             执行完第五行后,情况变为如图6.26所示。

                      

      提示:GC在进行回收对象前,会调用对象的finalize()方法,这是Object上定义的方法。如果在对象被回收前,有些事情想做,可以重新定义finalize()方法,不过要注意的是,何时启动GC,要视所采用的GC算法而定,也就是finalize()被调用的时机是无法确定的。在Effective Java 书中也建议,避免使用finalize()。如果对finalize()方法有兴趣,可以参考:

http://caterpillar.onlyfun.net/Gossip/JavaEssence/Finalize.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值