jvm学习的核心(五)---垃圾回收算法和常见垃圾回收器

news2024/10/1 1:18:58

文章目录

  • 1.垃圾回收算法
    • **1.1. 标记阶段**
    • **1.2. 清除阶段**
      • 1.2.1.标记清除算法
      • 1.2.2.标记复制算法
      • 1.2.3.标记整理算法
    • 1.3.引用
  • 2.常见的垃圾回收器
    • 2.1.Serial回收器
    • 2.2.ParNew回收器
    • 2.3.Parallel回收器
    • 2.4.CMS回收器
    • <font color = red>2.5.G1垃圾回收器
    • ZGC回收器(实验)

1.垃圾回收算法

首先,我们需要明确的是,垃圾回收主要包括以下几个阶段

1.1. 标记阶段

在标记阶段,我们举例两个算法
1.引用计数算法
这个算法是python使用的标记算法。

什么是引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值加1;当引用失效时,计数器值减1,引用数量为0的时候,则说明对象没有被任何引用指向,可以认定是”垃圾”对象

这种方法实现比较简单,且效率很高,但是无法解决循环引用的问题,因此在java中没有采用此算法(但是在Python中采用的是此算法)

2.可达性分析算法
这个算法是java使用的标记算法。

可达性分析算法的基本思路就是通过一系列名为”GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。
这个算法的基本思想是通过一系列称为“GC Roots”的对象作为起始点,从这些节点向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链(即GC Roots到对象不可达)时,则证明此对象是不可用的。
在这里插入图片描述

2.1.对象的finalization机制
在这里插入图片描述

这个机制我称之为救赎机制,当对象不可达的时候是且仅有一次救赎的机会的,如果这个方法重写过且没执行过,就会执行该方法。
如果这个对象被判定为有必要执行finalize()方法,那么这个对象将会放置在一个叫做F-Queuc的队列之中,并在稍后由一个由虚拟机自动建立的、低优先级的Finalizer线程去执行它。

1.2. 清除阶段

1.2.1.标记清除算法

当堆中的有效内存空间(available memory)被耗尽的时候,就会停止整个程序(也被称为stop the world),然后进行两项工作,第一项则是标记,第二项则是清除。

  • 标记:collector从引用根节点开始遍历,标记所有被引用的对象。一般是在对象的Header中记录为可达对象。
  • 清除:collector对堆内存从头到尾进行线性的遍历,如果发现某个对象在其Header中没有标记为可达对象,则将其回收。

1.2.2.标记复制算法

  • 将内存分为大小相同的两块,每次使用其中的一块。当这一块的内存使用完后,就将还存活的对象复制另一块去,然后再把使用的空间一次清理掉。
    优点:
    1.不会出现内存碎片问题
    2.对于存活对象少的区域(新生代),简单高效

    缺点:
    1.浪费空间并且移动对象开销大

1.2.3.标记整理算法

根据老年代的特点特出的一种标记算法,标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象回收,而是让所有存活的对象向一端移动,然后直接清理掉端边界以外的内存。
优点:
1.消除了标记-清除算法中,内存区域分散不连续的缺点,
2.消除了复制算法中内存减半的高额代价

缺点:
1.移动对象开销较大

1.3.引用

内存溢出的原因:存在大量无用的但又有强引用的对象无法回收

下面介绍java存在的4种引用:

1.强引用
我们经常使用的引用都是强引用,强引用触及的对象,即便程序报错也不可能回收 。

2.软引用
在程序要内存溢出之前,会把软引用对象列入二次回收范围,如果本次回收内存仍然不足以运行程序,则会把软引用对象回收,一般用于高速缓存。

3.弱引用
发现即回收,生存到下次内存回收之前,一般用于可有可无的缓存。

4.虚引用
对程序完全无影响,但是在回收之后可以收到通知

2.常见的垃圾回收器

垃圾回收器的性能指标:
在这里插入图片描述

1:吞吐量:即程序运行时间占总时间的百分比。
2:低延时:单次暂停的时间。

二者属于互斥状态,二者不可得兼
低延迟会缩短回收时间,因而会进行更多回收准备的无用功,因此吞吐量会对吞吐量产生负面影响。
在这里插入图片描述
注意:CMS在JDK9已经废弃,画虚线的表示在后来发行版本组个方式已经废弃

2.1.Serial回收器

在这里插入图片描述
这个收集器是一个单线程的收集器,但它的“单线程”的意义并不仅仅说明它只会使用一个CPU或一条收集线程去完成垃圾收集工作,更重要的是在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束(stop The world)。

  • serial收集器是最基本、历史最悠久的垃圾收集器了。JDK1.3之前回收新生代唯一的选择。
  • serial收集器作为HotSpot中client模式下的默认新生代垃圾收集器。serial收集器采用复制算法、事行回收和"stop-the-world”机制的方式执行内存回收。
  • 除了年轻代之外,serial收集器还提供用于执行老年代垃圾收集的serial old收集器。Serial old收集器同样也采用了串行回收
    和"stop the World"机制,只不过内存回收算法使用的是标记-压缩算法。
  • serial old是运行在client模式下默认的老年代的垃圾回收器
  • Serial old在server模式下主要有两个用途
    • ①与新生代的Parallelscavenge配合使用
    • ②作为老年代CMs收集器的后备垃圾收集方案

2.2.ParNew回收器

在这里插入图片描述

如果说serial cc是年轻代中的单线程垃圾收集器,那么ParNew收集器则是serial收集器的多线程版本。

  • ParNew是Parallel的缩写,New:只能处理的是新生代
  • ParNew收集器除了采用并行回收的方式执行内存回收外,两款垃圾收集器之间几乎没有任何区别。
  • ParNew收集器在年轻代中同样也是采用复制算法、"stop-the-world"机制。
  • ParNew是很多JVM运行在server模式下新生代的默认垃圾收集器。

2.3.Parallel回收器

Hotspot的年轻代中除了拥有ParNew收集器是基于并行回收的以外,Parallel Scavenge收集器同样也采用了复制算法、并行回收和"stopthe world”机制。

和ParNew收集器不同,Parallel scavenge收集器的目标则是达
一个可控制的吞吐量(Throughput),它也被称为吞吐量优先的垃圾收集器。
自适应调节策略也是Parallel scavenge与ParNew一个重要区别。

2.4.CMS回收器

在这里插入图片描述

  • 垃圾收集共分为五个阶段:上图所示初始标记和重新标记会有STW。
  • 重新标记,会用到三色标记里的增量更新算法。
  • 并发清理:这个阶段如果有新增对象会被标记为黑色不做任何处理主要优点:并发收集、低停顿。
  • 一XX:+UseConcMarkSweepGC:启用cms

CMS的弊端:
1.会产生内存碎片,导致并发清除后,用户线程可用的空间不足。在无法分配大对象的情况下,不得不提前触发Full GC。
2 .CMS收集器对cPu资源非常敏感。在并发阶段,它虽然不会导致用户停顿,但是会因为占用了一部分线程而导致应用程序变慢,总吞吐量会降低。
3.CMS收集器无法处理浮动垃圾。可能出现“Concurrent Mode railure"失败而导致另一次 Full GC 的产生。在并发标记阶段由于程序的工作线程和垃圾收集线程是同时运行或者交叉运行的,那么在并发标记阶段如果产生新的垃圾对象,CMs将无法对这些垃圾对象进行标记,最终会导致这些新产生的垃圾对象没有被及时回收,从而只能在下一次执行Gc时释放这些之前未被回收的内存空间。

2.5.G1垃圾回收器

G1垃圾回收器,是前沿成果

原因就在于应用程序所应对的业务越来越庞大、复杂,用户越来越多,没有cc就不能保证应用程序正常进行,而经常造成STw的Gc又跟不上实际的需求,所以才会不断地尝试对cc进行优化。G1 (Garbage-First)垃圾回收器是在Java7 update 4之后引入的一个新的垃圾回收器,是当今收集器技术发展的最前沿成果之一。

官方给G1设定的目标是在延迟可控的情况下获得尽可能高的吞吐量,所以才担当起“全功能收集器”的重任与期望。

  • 因为G1是一个并行回收器,它把堆内存分割为很多不相关的区域(Region)(物理上不连续的)。使用不同的Region来表示Eden、幸存者o区,幸存者1区,老年代等。

  • G1 Gc有计划地避免在整个Java堆中进行全区域的垃圾收集。G1跟踪各个 Region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region。由于这种方式的侧重点在于回收垃圾最大量的区间(Region),所以我们给G1一个名字:垃圾优先(Garbage First) 。

ZGC回收器(实验)

JVM的自动垃圾收集虽然减少了开发人员的工作,在一定程度上减少了内存泄漏的风险,但是由于GC是自动进行的,一些无法预知的事情有时候可能产生对应用有害的影响。

延迟增加导致应用的吞吐量和性能

随着时代发展,硬件会逐渐便宜,应用使用的内存将会越来越大,但是又不能增加延迟,降低吞吐量
ZGC保证,不管在什么情况下,延迟不会超过10毫秒。

ZGC最典型的特性是它是一款并发(concurrent)的GC,其它的特性如下:

它可以标记内存,复制和迁移(relocate)内存,所有的操作都是并发的,同时它有一个并发的引用处理器
其它的垃圾收集器都是使用store barriers,ZGC使用load barriers,用于跟踪内存

lock->unlock->read->load 读内存
use->assign->store->write 写内存

  • ZGC可以更加灵活的配置大小和策略,相比于G1,它可以更好的处理非常大(very large)对象的释放
  • ZGC只有一代,没有新生代,老年代什么的,但是ZGC可以支持局部压缩,在内存恢复和迁移(reclaim and relocate)时,ZGC仍然有很高的性能
  • ZGC依赖NUMA-aware(非均衡存储器访问),需要我们的内存支持这种特点

大部分图片以及内容总结自尚硅谷杜红康老师的尚硅谷宋红康JVM全套教程(详解java虚拟机)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/338408.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2月面经:真可惜...拿了小米的offer,字节却惨挂在三面

我是2月份参加字节跳动和华为的面试的&#xff0c;虽然我只拿下了小米的offer&#xff0c;但是我自己也满足了&#xff0c;想把经验分享出来&#xff0c;进而帮助更多跟我一样想进大厂的同行朋友们&#xff0c;希望大家可以拿到理想offer。 自我介绍 我是16年从南京工业大学毕…

java ssm idea高校图书借阅管理系统设计2z87z

本论文是以构建高校图书管理系统设计为目标&#xff0c;使用 jsp制作&#xff0c;由前台用户图书借阅、后台管理员图书分类两大部分组成。着重论述了系统设计分析&#xff0c;系统的实现&#xff08;用户注册模块&#xff0c;用户登录&#xff0c;用户图书借阅模块&#xff0c;…

ONNXRUNTUIME c++使用与相关资料(暂记)

下面的教程是在linux系统上运行的&#xff0c;如果想在windows系统上运行&#xff0c;可以看官方链接或中文教程https://bbs.huaweicloud.com/blogs/335706&#xff0c;官方链接中有完整的VS的带.sln的项目。 ONNXRUNTUIME OPENCV不支持某些算子(挤压层在opencv 中不支持) 安…

开关电源环路稳定性分析(10)——OPA和OTA型补偿器传递函数

大家好&#xff0c;这里是大话硬件。 在前面9讲的内容中将开关电源环路分析进行了梳理&#xff0c;我相信很多人即使都看完了&#xff0c;应该还是不会设计&#xff0c;而且还存在几个疑问。比如我随便举几个&#xff1a; 开关电源的带宽怎么设定&#xff1f;开关电源精度和什…

IDEA下java程序的调试(简易实例图示版)

在线排版不太好看&#xff0c;介意的读者可下载word下来看&#xff1a;https://download.csdn.net/download/xijinno1/87441301IDEA下java程序的简单调试-System.out.println首先本次进行调试的一个程序是实现从1累加到100的功能&#xff0c;是在IDEA下进行编写的。如图所示&am…

1626_MIT 6.828 lab1课程大纲学习过程整理

全部学习汇总&#xff1a; GreyZhang/g_unix: some basic learning about unix operating system. (github.com) 现在lab1的内容全都学习完了&#xff0c;该做的练习也都做了。接下来&#xff0c;整理一下自己看这一部分课程讲义的一些笔记。 整理之前&#xff0c;先把自己完成…

c# 跑马灯显示

//本文演示跑马灯//用到了线程、同步委托using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Threading;using System.IO;nam…

鲜花数据集实验结果总结

从read_split_data中得到&#xff1a;训练数据集&#xff0c;验证数据集&#xff0c;训练标签&#xff0c;验证标签。的所有的具体详细路径 数据集位置&#xff1a;https://download.csdn.net/download/guoguozgw/87437634 import os #一种轻量级的数据交换格式&#xff0c; …

常见漏洞之 struts2+ jboss

数据来源 本文仅用于信息安全的学习&#xff0c;请遵守相关法律法规&#xff0c;严禁用于非法途径。若观众因此作出任何危害网络安全的行为&#xff0c;后果自负&#xff0c;与本人无关。 01 Struts2相关介绍 》Struts2概述 》Struts2历史漏洞&#xff08;1&#xff09; 》…

【Linux】Linux多线程(下)

前言 大家好呀,欢迎来到我的Linux学习笔记~ 本篇承上Linux多线程创建,线程互斥(互斥锁),线程同步(条件变量),继下接着学习线程同步的另一个信号量,以及后序的线程池&#xff0c;线程的懒汉单例模式和其他锁相关知识。&#xff08;注意本篇博客代码居多&#xff09; Linux多线程…

C++005-C++选择与分支2

文章目录C005-C选择与分支2条件语句C实现else if 语句题目描述 根据成绩输出成绩等级ABCDEif嵌套语句题目描述 输出三个数中的最大值题目描述 模拟游戏登录switch语句三元运算符题目描述 输出三个数中的最大值-基于3元运算符题目描述 根据1-7输出星期1-星期日案例练习题目描述 …

php的api系统,php api 框架

本文目录一览&#xff1a; 1、php如何开发API接口2、什么是API&#xff1f;PHP的API怎么写&#xff1f;3、API和PHP是什么关系4、php中的API接口怎么写 ?5、如何使用PHP搭建一个restFul风格的API系统6、PHP 的API接口 php如何开发API接口 比如一个自定义函数&#xff1a;fun…

【遇见青山】项目难点:缓存击穿问题解决方案

【遇见青山】项目难点&#xff1a;缓存击穿问题解决方案1.缓存击穿互斥锁&#x1f512;方案逻辑过期方案2.基于互斥锁方案的具体实现3.基于逻辑过期方案的具体实现1.缓存击穿 缓存击穿问题也叫热点Key问题&#xff0c;就是一个被高并发访问并且缓存重建业务较复杂的key突然失效…

RuoYi-Cloud 部署

RuoYi-Cloud部署 1. 下载 点击右侧链接可以进入gitee的源码下载地址&#xff1a; 偌依微服务源码gitee下载地址 2. 数据库部署 依据如下步骤创建系统所需数据环境&#xff0c;脚本执行没有先后次序要求&#xff1a; 在Mysql 中创建 ry-cloud 主数据库&#xff0c;并执行 …

初学者必读:讲解 VC 下如何正确的创建、管理及发布项目

Visual C 的项目文件组成&#xff0c;以及如何正确的创建及管理项目。 本内容是初学者必须要掌握的。不能正确的管理项目&#xff0c;就不能进一步写有规模的程序。 一、项目下各种常见文件类型的功能 1. 代码文件 扩展名为 .cpp、.c、.h 等。 通常情况下&#xff0c;项目…

【Java】Help notes about JAVA

JAVA语言帮助笔记Java的安装与JDKJava命名规范JAVA的数据类型自动类型转换强制类型转换JAVA的运算符取余运算结果的符号逻辑运算的短路运算三元运算符运算符优先级JAVA的流程控制分支结构Java的安装与JDK JDK安装网站&#xff1a;https://www.oracle.com/java/technologies/do…

[项目设计]高并发内存池

目录 1、项目介绍 2、高并发内存池整体框架设计 3、thread cache <1>thread cache 哈希桶对齐规则 <2>Thread Cache类设计 4、Central Cache <1>Central Cache类设计 5、page cache <1>Page Cache类设计 6、性能分析 <1>定长内存池实现…

更换主板开机logo

更换主板开机logo前言详细操作步骤可能遇到的问题素材链接前言 在使用刀锋钛主板后发现&#xff0c;开机logo有些不符合个人喜好&#xff0c;如下图&#xff1a; 于是就有了更换主板logo的想法&#xff0c;确定用刷bios这一方法&#xff0c;注&#xff1a;刷BIOS之前一定要做…

MS14-064(OLE远程代码执行漏洞复现)

✅作者简介&#xff1a;CSDN内容合伙人、信息安全专业在校大学生&#x1f3c6; &#x1f525;系列专栏 &#xff1a;内网安全-漏洞复现 &#x1f4c3;新人博主 &#xff1a;欢迎点赞收藏关注&#xff0c;会回访&#xff01; &#x1f4ac;舞台再大&#xff0c;你不上台&#xf…

Java测试——selenium常见操作(2)

这篇博客继续讲解一些selenium的常见操作 selenium的下载与准备工作请看之前的博客&#xff1a;Java测试——selenium的安装与使用教程 先创建驱动 ChromeDriver driver new ChromeDriver();等待操作 我们上一篇博客讲到&#xff0c;有些时候代码执行过快&#xff0c;页面…