当前位置: 首页 > news >正文

JVM(七)--- 垃圾回收

目录

一、垃圾回收概述

1. 什么是垃圾

2. Java垃圾回收机制

二、垃圾回收相关算法

1. 垃圾标记算法

1.1 引用计数算法

1.2 可达性分析算法

2. 对象的finalization机制

3. 清除阶段

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

3.2 复制算法

3.3 标记-压缩算法

4. 分代收集算法

5. 增量收集算法

6. 分区算法

三、垃圾回收相关概念

1. System.gc()

2. 内存溢出

3.内存泄漏

4. Stop The World

5. 安全点与安全区域

6. 四种引用

6.1 软引用

6.2 弱引用

6.3 虚引用

四、垃圾回收器

1. GC的分类和性能指标

1.1 分类

1.2 性能指标

2. 不同的垃圾回收器

3. Serial回收器:串行回收

4. ParNew回收器:并行回收

5. Parallel回收器:吞吐量优先

6. CMS回收器:低延迟

7. G1垃圾回收器:区域化分代

7.1 优势与不足

7.2 适用场景

7.3 Region的介绍

7.4 记忆集

7.5 G1回收器垃圾回收过程

7.5.1 年轻代GC

7.5.2 并发标记过程

7.5.3 混合回收

8. 总结


一、垃圾回收概述

1. 什么是垃圾

垃圾是指在运行程序中没有任何指针指向的对象,这个对象就是需要被回收的垃圾。

2. Java垃圾回收机制

二、垃圾回收相关算法

1. 垃圾标记算法

1.1 引用计数算法

 

1.2 可达性分析算法

该算法可以有效解决在引用计数算法中循环引用的问题,防止内存泄露的发生。

“GC Roots”根集合就是一组必须活跃的引用。

如下图所示:

在Java语言中,GC Roots包括以下几类元素:

  • 虚拟机栈中引用的对象
  • 本地方法栈中引用的对象
  • 类静态属性引用的对象
  • 常量引用的对象(例如字符串常量池中的引用)
  • 所有被同步锁synchronized所持有的对象
  • Java虚拟机内部的引用

2. 对象的finalization机制

不要主动去调用某个对象的finalize()方法,应该交给垃圾回收机制调用。

由于finalize()方法的存在,虚拟机中的对象一般处于三种可能的状态

  1. 可触及的:从GC Roots根结点开始,可以到达的对象。
  2. 可复活的:对象的所有引用都被释放,但是对象有可能在finalize()中复活。
  3. 不可触及的:对象的finalize()被调用,并且没有复活,那么就会进入不可触及状态。

只有对象在不可触及状态的时候才可以被回收。

如果想要第一次被标记的对象复活,就需要重写finalize()方法。

3. 清除阶段

当成功区分出内存中存活对象和死亡对象之后,GC接下来的任务就是执行垃圾回收,释放掉无用对象所占用的空间。

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

优点:简单、方便。

缺点:

  • 效率不算高
  • 在进行GC的时候需要停止整个应用程序
  • 这种方式清理出来的空闲空间内存是不连续的,会产生内存碎片。需要维护一个空闲列表

3.2 复制算法

如下图所示:

A和B是两块内存空间,要对A进行垃圾回收的话,就将标记的对象复制到内存B中,然后清空内存A。之后放数据往内存B中放,若B要进行垃圾回收,则再往A中复制。

优点:

  • 没有清除过程,实现简单,运行高效
  • 复制过去后保证空间的连续性,不会出现“碎片”问题

缺点:

  • 内存空间始终有一半是空闲状态
  • 存活对象如果过多,那么时间开销和资源开销就会很大

3.3 标记-压缩算法

优点:

  • 消除了标记-清除算法中内存分散的缺点,当需要给新对象分配内存的时候,JVM只需要持有一个内存的起始地址即可。
  • 消除了复制算法中内存减半的高额代价。

缺点:

  • 效率较低
  • 移动对象的同时,如果对象被引用,还需要修改引用的地址
  • 移动过程中,需要全程暂停用户应用程序。即:STW

4. 分代收集算法

分代收集算法并不是一种具体的算法,而是一种思想。

不同对象的生命周期是不一样的。因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率。一般是把Java堆分为新生代和老年代,这样就可以根据各个区域的特点使用不同的回收算法。

目前几乎所有的GC都是采用分代收集算法执行垃圾回收的。

5. 增量收集算法

 为了解决STW状态,诞生了增量收集算法。

缺点:使用这种方法,虽然能减少系统的停顿时间。但是,因为线程切换和上下文转换的消耗,会使得垃圾回收的总体成本上升,造成系统吞吐量的下降。

6. 分区算法

如果设置的停顿时间短,那么就少回收几个region。如果停顿时间长,就多回收几个region。

三、垃圾回收相关概念

1. System.gc()

就是说,就算在程序中调用了System.gc()方法,该方法也不一定会调用垃圾回收器来对垃圾进行回收。

2. 内存溢出

内存溢出指的就是OOM异常,没有空闲内存,并且垃圾收集器也无法提供更多内存。

3.内存泄漏

严格来说,只有当对象不会再被程序用到了,但是GC又不能回收他们的情况,才叫内存泄露。

尽管内存泄露不会立刻引起程序崩溃,但是一旦发生内存泄露,程序中的可用内存就会被逐步蚕食,直到耗尽所有内存,最终出现OOM异常。

例如创建了许多static的变量,生命周期和类一样长,即便之后不用了,也无法被回收,导致内存泄漏。

上图的例子:红框框出来的对象都不再使用了,但是一个忘记断开的引用也会导致内存泄漏。

4. Stop The World

5. 安全点与安全区域

程序在执行过程中并非在所有地方都能停下来开始GC,只有在特定的位置才能停顿下来开始GC,这些位置称为“安全点”。

安全区域是指在一段代码片段中,对象的引用关系不会发生变化,在这个区域中的任何位置开始GC都是安全的。我们也可以把安全区域看作是被扩展的安全点。

6. 四种引用

6.1 软引用

软引用通常来实现内存敏感的缓存。例如高速缓存就用到软引用。第二次回收指的是在回收完那些不可达的对象之后内存还是不够,才进行第二次回收。

6.2 弱引用

弱引用也是用来描述那些非必须的对象,被弱引用关联的对象只能生存到下一次垃圾收集发生为止。

6.3 虚引用

虚引用不能单独使用,也无法通过虚引用来获取被引用的对象。当试图通过虚引用的get()方法获取对象时,总是null。

四、垃圾回收器

1. GC的分类和性能指标

1.1 分类

线程数分,可以分为串行垃圾回收器并行垃圾回收器

串行回收指的是在同一时间段内只允许有一个CPU用于执行垃圾回收操作,此时工作线程被暂停,直至垃圾回收工作结束。

并行收集可以运用多个CPU同时执行垃圾回收,因此提升了吞吐量,不过并行回收和串行回收一样,采用独占式,使用了STW机制。

按照工作模式分,可以分为并发式垃圾回收独占式垃圾回收。

碎片处理方式分,可以分为压缩式垃圾回收器非压缩式垃圾回收器。

工作的内存空间分,可分为年轻代垃圾回收器老年代垃圾回收器

1.2 性能指标

2. 不同的垃圾回收器

7种经典的垃圾回收器:

一个新生代的垃圾回收器需要组合一个老年代的垃圾回收器,组合关系如下。红色虚线表示JDK8之前的关系,绿色虚线在JDK14时弃用了。CMS垃圾回收器在JDK14也删除掉了

3. Serial回收器:串行回收

4. ParNew回收器:并行回收

ParNew收集器除了采用并行回收的方式执行内存回收外,它与Serial回收器几乎没有任何区别。PerNew收集器在年轻代中同样也是采用复制算法、“Stop-the-World”机制。

ParNew是很多JVM运行在Server模式下新生代的默认垃圾收集器。

5. Parallel回收器:吞吐量优先

6. CMS回收器:低延迟

CMS采用标记-清除算法,第一次实现了让垃圾回收线程与用户线程同时进行工作。

  1. 初始标记阶段:程序中所有的工作线程因为STW机制而出现短暂的暂停,这个阶段的主要任务仅仅只是标记出GC Roots能直接关联到的对象。一旦标记完成之后就会恢复所有的线程。这里的速度非常快
  2. 并发标记阶段:从GC Roots的能直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要停顿用户线程
  3. 重新标记阶段:由于在并发标记过程中,程序的工作线程和垃圾回收线程并发执行,因此为了修正并发标记期间,因为用户程序运行而导致标记产生变动的那一部分对象,这个阶段时间稍长,但也比第二阶段短的多。
  4. 并发清除阶段:此阶段清理掉的标记阶段判断的已经死亡的对象,释放空间。

CMS优点:

  • 并发收集
  • 低延迟

CMS缺点:

  • 会产生内存碎片
  • CMS收集器对CPU资源非常敏感
  • CMS收集器无法处理浮动垃圾

7. G1垃圾回收器:区域化分代

G1是一个并行回收器,它把堆内存分割为很多不相关的区域。使用不同的Region来表示Eden、Survivor0、Survivor1和老年代。

G1跟踪各个Region里面的垃圾堆积的价值大小,在后台维护一个优先列表每次根据允许的收集时间,优先回收价值最大的Region。

7.1 优势与不足

优势:

  • G1垃圾回收器兼顾并行与并发。
  • 将堆空间分为多个Region,既可以回收新生代,也可以回收老年代。
  • 空间整合:Region之间是复制算法,整体上看是标记-压缩算法。GC之后会将现有的资源放到一起,不会产生内存碎片。
  • 可预测的停顿时间模型:后台维护了一个优先列表,每次根据允许的收集时间,优先回收价值最高的最大的Region,保证G1收集器在有限时间内可以获取尽可能高的收集效率。

缺点:

7.2 适用场景

7.3 Region的介绍

 

7.4 记忆集

一个Region中的对象可能被其他任意Region中的对象所引用,判断对象是否存活,需要扫描整个Java堆才能保证准确。

无论是G1还是其他分代收集器,JVM都是使用Rset来避免全局扫描。即每一个Region都有一个对应的Rset,Rset中记录了有哪些区域的对象引用了该Region中的对象。

如下图所示:

7.5 G1回收器垃圾回收过程

G1的垃圾回收过程主要包括三个环节:年轻代GC、老年代并发标记过程、混合回收。

如果需要,Full GC还是继续存在的。它针对GC的评估失败提供了一种失败保护机制,即强力回收。

7.5.1 年轻代GC

7.5.2 并发标记过程

首先标记GC Roots直接可达的对象 --> 标记survivor区中可以直接到老年代的对象 --> 对整个堆进行标记(并发) --> 再次标记 --> 计算各个区域的GC回收比例 --> 并发清理。

7.5.3 混合回收

第二阶段老年代Region中全是垃圾的被回收了,部分为垃圾的在第三阶段--混合回收的时候被回收。

8. 总结

http://www.dtcms.com/a/439512.html

相关文章:

  • 专门制作网站郑州男科医院哪家治疗比较好
  • 网站开发 需求文档结构设计网站推荐
  • 自定义异常类中的super(msg)的作用
  • 我想卖自己做的鞋子 上哪个网站好扬州市建筑信息平台
  • 十里河网站建设百度做营销网站多少钱
  • 新版网页传奇网站优化怎么做外链
  • 衡阳网站建设icp备网页设计技术论文范文
  • Linux驱动开发核心概念详解 - 从入门到精通
  • 深圳市建设工程交易服务中心网站在南海建设工程交易中心网站
  • 寻找哈尔滨网站建设服务器内部打不开网站
  • 函数展开成幂级数的方法总结
  • 自己可以做类似拓者的网站吗郑州网站建设行情
  • 中国顶级 GEO 优化专家孟庆涛:用 15 年积淀定义 2025 年 GEO 优化新标准
  • 建筑方案的网站wordpress首页做全屏
  • 建设银行手机官方网站下载安装推荐大良营销网站建设
  • 华为手机网站建设策划方案wordpress文章模块化
  • 修改wordpress用户密码深圳网站营销seo电话
  • 杭州建设企业网站的网络规划设计师考海明码吗
  • DAY24 方法引用、Base64、正则、lombok
  • 大学网站建设包括哪些课程专业网站搭建报价
  • 网站上的图片做多大免费网站整站模板源码
  • 江苏建设厅官方网站安全员长沙建长沙建网站公司
  • 杭州做网站小芒上海闵行区租房价格
  • 做美食的网站可以放些小图片简历网站后怎样才能被谷歌 百度收录吗
  • 8.3 JavaScript 抽象相等比较算法
  • 10.3 作业
  • 商城网站建设模板下载wordpress空2格插件
  • 房地产图文制作网站wordpress修改了访问地址
  • NSSA区域 概念题目
  • 燕莎网站建设微软雅黑适合于做网站吗