【JVM】关于JVM,你需要掌握这些 | 一文彻底吃透JVM系列( 三 )

  1. 标记-清除算法
  2. 复制算法
  3. 标记-整理算法
  4. 分代收集算法
标记-清除算法(Mark-Sweep)什么是标记-清除算法?分为标记和清除两个阶段 。首先标记出所有需要回收的对象 , 在标记完成后统一回收被标记的对象 。
有什么缺点?效率问题:标记和清除过程的效率都不高 。
空间问题:标记清除之后会产生大量不连续的内存碎片 , 空间碎片太多可能导致 , 程序分配较大对象时无法找到足够的连续内存 , 不得不提前出发另一次垃圾收集动作 。
【JVM】关于JVM,你需要掌握这些 | 一文彻底吃透JVM系列

文章插图
复制算法(Copying)- 新生代将可用内存按容量划分为大小相等的两块 , 每次只使用其中一块 。当这一块的内存用完了 , 就将存活着的对象复制到另一块上面 , 然后再把已经使用过的内存空间一次清理掉 。
优点复制算法使得每次都是针对其中的一块进行内存回收 , 内存分配时也不用考虑内存碎片等复杂情况 , 只要移动堆顶指针 , 按顺序分配内存即可 , 实现简单 , 运行高效 。
缺点将内存缩小为原来的一半 。在对象存活率较高时 , 需要执行较多的复制操作 , 效率会变低 。
【JVM】关于JVM,你需要掌握这些 | 一文彻底吃透JVM系列

文章插图
应用商业的虚拟机都采用复制算法来回收新生代 。因为新生代中的对象容易死亡 , 所以并不需要按照1:1的比例划分内存空间 , 而是将内存分为一块较大的 Eden 空间和两块较小的 Survivor 空间 。每次使用 Eden 和其中的一块 Survivor 。
当回收时 , 将 Eden 和 Survivor 中还存活的对象一次性拷贝到另外一块 Survivor 空间上 , 最后清理掉 Eden 和刚才用过的 Survivor 空间 。Hotspot 虚拟机默认 Eden 和 Survivor 的大小比例是8:1 , 也就是每次新生代中可用内存空间为整个新生代容量的90%(80% + 10%) , 只有10%的内存是会被“浪费”的 。
标记-整理算法(Mark-Compact)-老年代标记过程仍然与“标记-清除”算法一样 , 但不是直接对可回收对象进行清理 , 而是让所有存活的对象向一端移动 , 然后直接清理掉边界以外的内存 。
【JVM】关于JVM,你需要掌握这些 | 一文彻底吃透JVM系列

文章插图
分代收集算法根据对象的存活周期 , 将内存划分为几块 。一般是把 Java 堆分为新生代和老年代 , 这样就可以根据各个年代的特点 , 采用最适当的收集算法 。
  • 新生代:每次垃圾收集时会有大批对象死去 , 只有少量存活 , 所以选择复制算法 , 只需要少量存活对象的复制成本就可以完成收集 。
  • 老年代:对象存活率高、没有额外空间对它进行分配担保 , 必须使用“标记-清理”或“标记-整理”算法进行回收 。
Minor GC 和 Full GC有什么区别?Minor GC:新生代 GC , 指发生在新生代的垃圾收集动作 , 因为 Java 对象大多死亡频繁 , 所以 Minor GC 非常频繁 , 一般回收速度较快 。Full GC:老年代 GC , 也叫 Major GC , 速度一般比 Minor GC 慢 10 倍以上 。
Java 内存为什么要将堆内存分区?对于一个大型的系统 , 当创建的对象及方法变量比较多时 , 即堆内存中的对象比较多 , 如果逐一分析对象是否该回收 , 效率很低 。分区是为了进行模块化管理 , 管理不同的对象及变量 , 以提高 JVM 的执行效率 。

经验总结扩展阅读