JVM内存管理—内存回收—垃圾收集算法理论

垃圾收集算法包括:Mark-Sweep算法、Copying算法、Mark-Compact算法。

概述:HotSpot是按照分年代进行回收Generational Collection。分为新生代、老年代、永久代

前言

根据对象的生命周期的不同,将内存划分为几块,一般把Java堆分为新生代和老年代,把方法区划分为永久代

  1. 在新生代中,每次垃圾回收都有大量的对象死去,只有少量的对象存活,所以只需额外较小的空间来存储这些存活的对象,适用于复制算法

  2. 老年代对象存活率高,每次回收都有大量的对象存活,没有额外的空间进行分配担保,所以一般使用标记-清除,标记-整理算法进行回收。

  3. 永久代在HotSpot是否收集可以通过参数进行设置,但是收集性价比低,没有对新生代的回收来的实惠(释放大量的空间)。

Copying(复制算法HotSpot的实现)

为了解决Mark-Sweep算法的效率问题

  • 将内存空间划分为一块较大的空间Eden和两块Survivor,比例为8:1:1。记为E、S1、S2
  • 每次使用Eden和其中一块Survivor,记为E、S1。当进行垃圾回收时,将E、S1的存活的对象复制到S2上,然后直接清除掉S1,并对E用过的区域进行清理下次新生代分配对象会分配在E上如果S2上的内存空间不够存储上一次垃圾收集新生代存活的对象(E、S1上)会向老年代内存空间上进行分配担保(借一些空间来存储,然后保证使用完后还回去)
  • 特点:分配效率高,清除后的空间是连续的。在HotSpot中常用来对新生代进行回收

Mark-Sweep(标记-清除算法)

  • 顾名思义,算法分为两步:标记出所有需要回收的对象,标记完成后统一进行回收。
  • 缺点:这是最基本的垃圾收集算法
    1. 标记和清除阶段的效率都不高。
    2. 标记清除后将会产生大量不连续的空间,导致想要分配大对象时,还需在进行一次垃圾回收。

Mark-Compact(标记-整理算法)

  • 标记存活的对象,然后将标记的对象向一端移动,这样存活的对象就都聚到一起了,然后就可以清除存活边界以外的内存空间了。
  • 得到规整连续的空闲空间分配新对象效率高,专门对老年代对象进行回收

永久代中的垃圾收集

方法区哪些对象需要进行回收?
无用的常量

常量
  1. 字面量"hhhhh”等不是通过new创建的字符串(其实这一部分称为 String Constant Pool),final int等一些基本数据类型常量
  2. 类(接口)、方法、字段等的符号引用
无用的类(Class对象)

满足下面三个条件的类对象才会被回收(HotSpot中必须设置对应的参数,使能对永久代的回收)

  1. 该类的所有实例对象已被回收,即Java堆中不存在此类的实例
  2. 加载该类的ClassLoader已经被回收
  3. 该类对应的java.lang.Class对象没有在任何地方被引用,即无法再通过反射类访问这个类的方法。

推荐阅读更多精彩内容