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,控制引用变量的生命周期,从而控制对象的生命周期。

阅读更多
个人分类: Java
想对作者说点什么? 我来说一句

IBM JVM GC 技术文档

2010年02月22日 534KB 下载

JVM、GC详解及调优

2018年06月04日 784KB 下载

SUN HotSpot JVM GC

2011年09月30日 2.49MB 下载

java程序启动参数设置优化

2018年06月11日 322KB 下载

垃圾回收的算法与实现

2018年01月26日 33MB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭