JVM 垃圾回收

用户头像
superman
关注
发布于: 2020 年 08 月 02 日



秒杀作业链接:https://xie.infoq.cn/article/1895cfec0ffe4f3c392ee95cf



摘要:

  • jvm垃圾回收主要指对堆内不使用对象回收

  • 回收过程分为:识别垃圾,回收垃圾

  • 识别垃圾:通过可达性分析识别

  • 回收垃圾有3中回收方法。标记清除,复制,标记压缩

  • JVM对堆进行分代,新生代,老年代,不同代采用不同的回收方法。

  • 新生代一般采用复制,老年代一般采用标记压缩。

  • 垃圾回收有吞了量,用户线程暂停时长两种指标,不同场景采用要求不同。

  • jvm提供多种回收器可组合使用。

  • 当前推荐G1回收器。G1将空间划分为多个小区域,分别回收,暂停时间短。



1: JVM的内存划分

java程序由JVM执行,程序执行时JVM的内存主要包括一下几部分:

程序计数器,Java栈(VM Stack),本地方法栈,方法区,堆。



各个区域包括的内容

程序计数器:类似CPU的PC,记录执行到哪个指令了。

特点:线程独享,数据量小,随时变。

JAVA栈:线程独享,以栈结构存放一个个栈帧,一个栈帧对应一个方法调用。

          栈帧内包括:局部变量,操作数栈,返回地址,常量池引用等,执行本方法需要的信息。

本分方法栈:执行本地方法的栈,线程独享。

方法区:全局共享,主要存放加载的类的信息,静态变量,常量池。

堆:全局共享,存放对象,垃圾回收主要管理区域。



2:垃圾回收

2.1 背景与目标

垃圾回收-释放堆内不再使用的对象占用的空间

占用程序内存最多的是堆空间,其它区域要么变化小(方法区,要么不断变化(计数器,随时就清理(栈)。

c语言时代堆空间的申请释放由程序员控制,java程序将程序员从堆管理中解放出来,由jvm管理堆,将堆中不再使用的对象回收。



对象地址分配与引用

对象内地址是连续的,对象地址之前起始地址,对象引用地址指向逻辑地址(对象表,逻辑地址的翻译到物理地址由jvm控制)。

java对象是整体分配到一块区域的,各个字段的访问由对象地址(起始地址)+字段偏移量访问。



对象的某个字段是对象,回收时回收的是这个引用占用的空间,被引用对象的计数相当于减掉一个。将来没有引用了就可以回收。



2.2 垃圾回收步骤

将不再使用的对象(垃圾)回收,需要两步

1:识别垃圾

2:回收垃圾

 

2.2.1 识别垃圾-可达性分析

从GCRoots 出发, 将这些对象及这些对象引用的对象进行标记,沿着被标记的对象继续寻找并标记。最后所有被标记的对象就是需要的对象,未被标记的对象就是不需要的-垃圾。

GCRoots包括:虚拟机栈,本地方法栈中引用的对象,静态属性引用的复习,方法区常量引用的对象。

2.2.2 回收垃圾方法

 常用的牢记回收算法有3种

1:标记-清除

      识别出垃圾后,将垃圾删除,释放占用的空间。

       问题:导致内存碎片多,分配效率低。

2:复制

       将空间分层两部分,把活的对象复制过去,两一块空间回收。

        特点:内存浪费,无碎片

3:标记整理(压缩)

       分两步,第一步用标记清理方式,然后将活的对象移动-压缩到一个连续空间。

       可解决碎片问题。



2.3 JVM的垃圾回收方法

 

2.3.1 堆内分代

程序运行时堆内对象大部分分配后很快就不再使用,只有很小比例的对象会存活较长的时间。针对这个特点,jvm将堆内空间划分为多个区域,分别采用不同的回收策略。

具体划分:

JVM堆(Heap)= 新生代(Young) + 旧生代(Tenured)

新生代(Young)= Eden区 + Survivor区

Survivor=两个,交叉扮演 From, To.







2.3.2 分代回收

MinorGC(新生代回收)

新创建对象分配到Edge区,内存不足时先回收新生代(Minor GC)。

JVM进行Minor GC时,将Eden中还存活的对象拷贝到Survivor区中,还会将Survivor区中还存活的对象拷贝到Old区中(可设置存活多少次拷贝到老年区)。在这种GC模式下,JVM为了提升GC效率, 将Survivor区分为S0和S1,这样就可以将对象回收和对象晋升分离开来。

新生代一般采用复制算法回收

 

FullGC(老年代回收)

新生代回收后空间不足进行老年代回收。

老年代大部分存活时间长,采用标记整理(压缩)方法进行回收。

2.3.3 回收指标与回收器

垃圾回成本(指标)与程序选择

1:垃圾收集的吞吐量(收集时间占比):

2:垃圾回收时导致用户线程暂停的停顿时间长度。

 

不同程序对这些指标的要求不同,实时在线处理的需要尽量减少用户线程暂停时间。

后台批处理的程序主要回收吞吐量高就行。对暂停时间不敏感。

 

JVM回收器

JVM提供多种回收器,分别适用不同的场景,可根据场景情况组合使用

主要包括:

Parallel Old: 多个线程对老年代进行标记压缩。后台批处理程序适合。

Serial Old:串行对老年代标记压缩

CMS: 对老年代回收,多个线程与用户线程一起执行(分析阶段),暂停时间短

G1: 当前推荐的回收器。

    将内存空间在分成很多的小区域。回收的时候一个小区域回收。每次暂停时间都比较短。



参考

极客时间架构师训练营-李智慧

https://www.jianshu.com/p/f6197bfc61b0

https://www.cnblogs.com/dolphin0520/p/3613043.html



发布于: 2020 年 08 月 02 日 阅读数: 58
用户头像

superman

关注

还未添加个人签名 2018.07.20 加入

还未添加个人简介

评论

发布
暂无评论
JVM垃圾回收