深入理解java虚拟机-第二章:垃圾收集算法

来源:互联网 发布:在职研究生 知乎 编辑:程序博客网 时间:2024/06/04 21:20

一、垃圾收集区域

a)重点区域:Java堆和方法区

      一个接口中多个实现类需要的内存可能不一样,一个方法中多个分支需要的内存也不一样。

      永久代的垃圾回收主要收集两部分:

      ++废弃常量:没有任何地方引用。

      ++无用的类:1.该类所有的实例都已被回收,在java堆中不存在该类的任何实例;2.classloader被回收;3.该类对应的java.lang.Class没有在任何地方被引用,无法通过反射访问该类的方法。

b)一般区域:程序计数器、虚拟机栈、本地方法栈

      这三个区域在方法结束和线程结束之后,内存跟着回收了。


二、垃圾收集算法

a)引用计数算法(没有选用)

      原理: 给对象添加一个引用计数器,每当有一个地方引用它时,计数器值加1,当引用失效时,引用值减1;任何时候计数器为0的对象将不再被调用。java不选用该算法是因为它无法解决对象之间相互引用的问题。

b)根搜索算法(主流)

      原理:以一系列名为“GC roots”作为起始点,通过根节点向下搜索,搜索走过的路径称为引用链;当一个对象到达“GC roots”没有任何引用链相连时(用图论的话说就是从gc roots到这个对象不可达),则证明该对象是不可用的。

      在Java语言中,可作为GC roots的对象包括下面几种:

      1.虚拟机栈中的引用对象(栈帧中的本地变量表)

      2.方法区中的类静态属性引用的对象。

      3.方法区中的常量引用的对象。

      4.本地方法栈中JNI的引用对象(即一般说的native方法)

     | 引用:如果reference类型的数据中存储的数值代表另一块内存的起始地址,则称这块内存代表着一个引用。引用在jdk1.2之后分为4类:

     | 强引用:垃圾回收器永远不会回收掉被引用的对象。

     | 软引用:一些还有用但是并非必须的对象,对软引用关联的对象,将在系统发生内存溢出之前进行第二次回收。

     | 弱引用:非必须对象,比软引用还要弱。只能生存到下一次垃圾回收发生之前,

     | 虚引用:最弱的一种引用关系。为一个对象设置虚引用唯一的目的就是希望这个对象在被收集器回收是收到一个系统通知。

     -----------------------------------------------------------------------------------------------------

c)标记-清除算法

  原理:首先标记出所有需要回收的对象,在标记完成之后统一回收掉所有被标记的对象。

  缺点:1.效率不高。

              2.清除之后造成内存的不连续,这样在分配大的对象时无法找到最够内存就会不得不触发下一次的垃圾回收动作。


d)复制算法

  原理:将内存分为大小相同的两块,每次只使用其中的一块;当这一块内存用完了,就将存活的对象复制到另外一块,然后一次将内存清理掉。

  优点:不用考虑碎片的问题,只要移动堆顶指针,按顺序分配内存即可;实现简单,运行高效。

  缺点:内存缩为原来的一半。


e)标记-整理算法

  原理:标记过程与‘标记-清除’算法一样,但是标记过后,不清除,而是将存活的对象向另一端进行移动。然后直接清除掉边界以为的内存。

  优点:清理之后,可获得连续内存。

  缺点:移动对象的过程降低效率。


f)分代收集算法

  原理:根据对象存活周期不同将内存分为不同的块。一般分为新生代和老年代。新生代中每次垃圾收集都会发现大批对象死去,只有少量存活,则用复制清理。

      而老年代中对象存活率高,没有额外空间,就是用“标记-清除”和“标记-整理”。

 



      

阅读全文
0 0
原创粉丝点击