java垃圾回收算法(记录)

java垃圾回收算法

  1. 引用计数算法

引数计数算法是垃圾收集器中的早期策略。堆中的每个对象实例都有一个引用计数,当一个对象被创建时,且将该对象实例分配给一个引用变量,该对象实例的引用计数设置为1。特别地当一个对象实例被垃圾收集时,它引用的任何对象实例的引用计数器均为减1。任何引用计数器为0的对象实例可以被当做垃圾收集。 java垃圾回收算法(记录)

  1. 根搜索算法

通过一系列的名为"GC Root"的对象作为起点,从这些节点向下搜索,搜索锁走过的路径称为引用链(Reference chain),当一个对象到GC Root没有任何引用链相连时,则该对象不可达,该对象是不可使用的,垃圾收集器将回收其所占内存。 java垃圾回收算法(记录)

在java语言中,可作为GC Root的对象包括以下几种对象:

  • java虚拟机栈中的引用对象。
  • 方法区中的类静态属性引用的对象。
  • 方法区中的常量引用的对象。
  • 本地方法栈中JNI本地方法的引用对象。
  1. 标记清除算法

标记清除算法是最基础的垃圾算法,分为“标记”和“清除”两个阶段:该算法首先从根集合进行扫描,对存活的对象进行标记,标记完毕后,再扫描整个空间中未被标记的对象并进行回收。 java垃圾回收算法(记录)

  1. 复制算法

此算法把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另外一个区域中。次算法每次只处理正在使用中的对象,因此复制成本比较小,同时复制过去以后还能进行相应的内存整理,不过出现“碎片”问题。当然,此算法的缺点也是很明显的,就是需要两倍内存空间。 java垃圾回收算法(记录)

  1. 标记调整算法

此算法结合了 “标记-清除”和“复制”两个算法的优点。也是分两阶段,第一阶段从根节点开始标记所有被引用对象,第二阶段遍历整个堆,把清除未标记对象并且把存活对象 “压缩”到堆的其中一块,按顺序排放。此算法避免了“标记-清除”的碎片问题,同时也避免了“复制”算法的空间问题。 java垃圾回收算法(记录)java垃圾回收算法(记录)

  1. 分代算法

基于对对象生命周期分析后得出的垃圾回收算法。把对象分为年青代、年老代、持久代,对不同生命周期的对象使用不同的算法(上述方式中的一个)进行回收。现在的垃圾回收器(从J2SE1.2开始)都是使用此算法的。

  • Young(年轻代) 年轻代分三个区。一个Eden区,两个 Survivor区。大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到Survivor区(两个中的一个),当这个 Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当这个Survivor去也满了的时候,从第一个Survivor区复制过来的并且此时还存活的对象,将被复制“年老区(Tenured)”。需要注意,Survivor的两个区是对称的,没先后关系,所以同一个区中可能同时存在从Eden复制过来对象,和从前一个Survivor复制过来的对象,而复制到年老区的只有从第一个Survivor去过来的对象。而且,Survivor区总有一个是空的。
  • Tenured(年老代) 年老代存放从年轻代存活的对象。一般来说年老代存放的都是生命期较长的对象。
  • Perm(永久代) 用于存放静态文件,如今Java类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如Hibernate等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类。持久代大小通过-XX:MaxPermSize=<N>进行设置。 java垃圾回收算法(记录)

转载于:https://my.oschina.net/cqyj/blog/1570411