一篇帮你搞定JVM中的垃圾回收的基本知识(超级详细)

Posted adventure.Li

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一篇帮你搞定JVM中的垃圾回收的基本知识(超级详细)相关的知识,希望对你有一定的参考价值。

一、总体框架

在这里插入图片描述
二、知识介绍

  1. 如何确定垃圾?

(1)引用计数法

Java中,引用和对象是关联的,操作对象必须用引用进行。因此,对象如果没有任何与之相关联的引用,即他们的引用数为0,则该对象不太可能用到,即可回收。

(2)可达性分析

为了解决引用计数法存在的循环引用问题(有点类似死锁),Java使用可达性分析的方法。
通过一系列的“GC roots”对象作为起点搜索。如果在 “GC roots”和一个对象之间没有可达路径,则该对象是不可达。另外,不可达对象不等价于回收对象,不可达对象变为可回收对象,需要至少两次标记。

  1. 主要算法
算法步骤缺 点
标记清除算法(mark-sweep)最基础的垃圾回收算法,分为标注(标记需要回收的对象)和清除(收回占用的被标记的对象空间,变为未使用的空间)两阶段。内存碎片化验证,后续大对象可能找不到利用空间。
复制算法(copying)按内存容量将内存划分为等大小的两块。每次只用其中一块,当这块满后将存活对象复制到另外一块将内存压缩到原来的一半。
标记整理算法(mark-compact)结合以上两种,标记后不是清理对象,而是将存活对象移向内存的另一端
  1. 分代收集算法

是目前大部分JVM所采用的方法。核心思想根据对象的存活的不同生命周期进行内存划分(新生代(新对象频繁创建)和老生代(少量垃圾回收)),然后不同区域选择不同算法进行回收。

新生代:复制算法。
老生代:标记复制算法。
在这里插入图片描述

  1. Java中的四种引用类型

(1)强引用(把对象复制给一个引用变量,这个变量就是强引用)
(2)软引用(SolfReference类来实现)
(3)弱引用
(4)虚引用

  1. 分区收集算法

整个堆区划分为连续的不同小区间(分代是根据对象的生命周期),每个区间独立使用,独立回收,好处是可以控制一次回收多少个小区间。

  1. GC垃圾回收器

新生代:Serail、ParNew、Parallel Scavenge.
年老代:CMS、MSC、Parallel Old。

(1)Serial 垃圾回收器 (单线程、复制算法)

最基本的垃圾回收器,使用复制算法,JDK1.3.1之前新生代唯一的垃圾回收器。单线程,没有线程交互的开销,简单而高效。
JVM运行在Client模式下默认的新生代垃圾回收器。

JVM有两种运行模式Server与Client。两种模式的区别在于,Client模式启动速度较快,Server模式启动较慢;但是启动进入稳定期长期运行之后Server模式的程序运行速度比Client要快很多。这是因为Server模式启动的JVM采用的是重量级的虚拟机,对程序采用了更多的优化;而Client模式启动的JVM采用的是轻量级的虚拟机。所以Server启动慢,但稳定后速度比Client远远要快。参考

(2)ParNew (Serial+多线程)

Serial的多线程版。JVM运行在Server模式下默认的新生代垃圾回收器。

(3)Parallel Scavenge (多线程复制算法、高效)

也是新生代的垃圾回收器,他重点关注程序达到一个可控制的吞吐量,主要适用于在后台运行不需要太多交互的任务。自适应调节策略是Parallel Scavenge与ParNew 的重要区别。

(4)CMS收集器(多线程标记清除算法)

年老代垃圾收集器,主要目标是获取最短垃圾回收停顿时间。采用多线程的标记-清除算法。

(5)G1收集器

目前垃圾回收理论发展最前沿成果,相比较CMS,有以下两优点:
1.基于标记-整理算法,不产生内存碎片
2.可以精准控制停顿时间

以上是关于一篇帮你搞定JVM中的垃圾回收的基本知识(超级详细)的主要内容,如果未能解决你的问题,请参考以下文章

深度分析:Java中如何如理异常,一篇帮你搞定!

深度分析:Java中如何如理异常,一篇帮你搞定!

看完这篇总结,你会发现其实spring面试真的没那么难,一篇帮你彻底搞定spring。

看完这篇总结,你会发现其实spring面试真的没那么难,一篇帮你彻底搞定spring。

搞定 JVM 垃圾回收就是这么简单

面试被问如何保证缓存与数据库的双写一致性?这篇帮你搞定