GC

  1.垃圾回收的必要性

     当对象被创建时,会在Java虚拟机中分配一块内存(内存分配-》默认值-》初始化值),在JVM的生命周期中,Java程序在不断地创建对象,这些对象在内存运行时数据区的堆区有一块内存空间,如果这些对象的内存不被及时回收,会导致内存空间不足,因此要有一种措施及时回收无用对象的内存,保证内存能够被重复利用。

     在传统的编程语言中,内存回收的工作由程序完成,程序显式地为对象分配内存,显式地回收,可能导致该回收的没有回收(会导致内存溢出),不该回收的反而回收了(重复回收内存会导致内存冲突)。

  2.java中的内存回收工作由JVM进程的一个称为垃圾回收器的系统级线程完成(因此GC是JVM实现的一部分,不同的JVM对GC的实现不同,因此可能要考虑到平台无关性,不能依靠及时性确保程序的正确性),它负责回收无用对象的内存,回收内存的过程称为垃圾回收。

  3.垃圾回收的特点

     a.只有当对象不再被任何变量引用时,它的内存才可能被回收;

     b.程序无法迫使垃圾回收器立即执行垃圾回收操作(GC是否执行,何时执行都不能够确定,这是java的一个弊端,因此不能指望利用GC实现一定发生,一定在某点发生的操作)

     c.垃圾回收器在回收内存之前会调用finalize()方法,该方法有可能使对象复活,导致垃圾回收器取消回收该对象的操作。

      finalize()方法是GC执行内存回收之前调用的方法,它的初衷是负责完成内存回收之前的一系列准备工作,但是可以覆盖该方法,使它完成将对象由可复活状态转到可触及状态的功能

     然而,finalize()具有不确定性,因为该方法由GC线程执行,由于GC线程的不确定性,导致该方法是否执行,何时执行都具有不确定,因此,如果某个功能要求一定要执行,或者一定在某点执行,不能在finalize()方法中定义。

 

  4.从垃圾回收器的角度看对象的状态

      a.可触及状态,只要程序中还有变量引用对象,该对象就处于可触及状态《此时垃圾回收器什么都不做》;

从B阶段开始由JVM接手

      b.可复活状态,程序中没有变量引用对象,在这个状态中,垃圾回收器会准备释放对象占用的内存,释放之前,调用它的和其他处于可复活状态的对象的finalize()方法,这些finalize()方法会使对象重新回到可触及状态;

      c.不可触及状态 当JVM执行完所有的finalize()方法,都不能使对象回到可触及状态时,对象就进入不可触及状态,这时,垃圾回收器会真正回收对象的内存

 

  5.垃圾回收的时间

      (1)程序只能够决定对象什么时候能够变为可复活状态,即在程序中不让任何变量引用该对象,但是程序无法决定垃圾回收器什么时候执行,即什么时候执行finalize()方法,什么时候让对象处于不可触及状态,什么时候回收对象的内存。

      (2)对象生命周期:从对象被创建开始,一直到没有任何变量引用该对象(即当对象处于可恢复状态时,它的生命周期就已经结束了)。

      (3)程序无法决定垃圾回收器什么时候回收无用对象的内存,垃圾回收器作为一个地优先级的线程独立运行,可以在程序中使用System.gc()或者Runtime.gc()提示垃圾回收器进行垃圾回收操作,但是这并不能够决定垃圾回收器什么时候开始工作,甚至不能够保证垃圾回收器一定会工作。

 

   6.对象的finalize()方法

      (1)垃圾回收器在回收无用对象的内存时,会调用该对象的finalize()方法,但如果垃圾回收器在程序运行结束之前没有进行垃圾回收操作,对象的finalize()方法就不会得到调用。在Java的Object类中定义了finalize()方法,访问权限定为protected,任何类都可以覆盖该方法,完成释放无用对象资源的相关操作。

      (2)gc()垃圾回收的操作对程序是透明的,即程序无法保证gc()一定会执行垃圾回收操作,也无法保证gc()在何时执行垃圾回收操作,一般情况下,除非gc()认为程序需要额外的资源,否则gc()不会进行垃圾回收操作,即使是显式调用System.gc()或者Runtime.gc(),也不能保证垃圾回收操作一定会执行,对象的finalize()方法一定会执行。

      (3)finalize()方法

             a. 是否执行,何时执行都不确定

             b. Object中的本意是释放无用对象的资源,但是可以通过方法覆盖使它具有使无用对象(处于可复活状态)的对象转为可触及状态的功能;

             c. 在finalize()中抛出的任何异常,gc()都不执行。

      (4)注意,gc()线程执行finalize()方法,在垃圾哦回收之前执行无用对象的finalize()方法;

      (5)finalize()方法的本意是释放无用对象的资源,但是可以通过覆盖,使对象转为可触及装填;

      (6)finalize()  vs  try...catch...finally

              finalize()方法不适用于以下两种情况:

                操作一定要执行

                操作必须在某个确定的时刻执行

              具有上述特点的操作应该放于finally代码块中

      (7)程序中清楚过期的对象引用

      (8)程序中应该及时清除无用对象的引用,这样可以使对象处于可复活状态(无用状态,这点程序可以做到),gc可以进行垃圾回收,但是到底执不执行,何时执行,依旧不确定

       (9)程序可以通过控制引用变量的生命周期控制对象的生命周期(当程序中没有变量引用对象时,该对象的生命周期就结束了,因此可以通过控制变量来控制对象的生命周期)

               如

               private static final FEMALE = new Gender("女");

                Gender对象的生命周期取决于FEMALE的生命周期(因为是final,FEMALE不能够指向其他对象),而FEMALE生命周期取决于代表Gender类的Class对象的生命周期,如果Gender类不被卸载,即Class对象不置为null,Class对象会常驻内存,直到程序运行结束。(此处注意,类的生命周期的结束通过将代表类的Class对象职位null实现)

 

              再如:

              局部变量,在方法结束后结束生命周期,它原来所引用的对象不再被任何变量引用,对象的生命周期结束。

       (10)可以将引用变量置为null,控制引用变量的生命周期,从而控制对象的生命周期。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值