JVM知识点整理

news2024/9/27 19:18:08

JVM

  • 回收哪个区域?
      • 关联面试题:fullgc会回收方法区(元空间)吗?
  • 怎么判断对象可以被回收了
    • 关联面试题:哪些对象可以作为 GC Root (两栈两方法)
  • JVM GC什么时候执行?
  • 分代回收机制
    • 思考:假如eden区80m,老年代200m,一个对象90m?
    • 各区域触发垃圾回收的类型与解释
      • 新生代
        • 新生代GC收集(类比倒水)
      • 老年代(为什么老年代的回收耗时,比新生代更长呢)
      • 跨代引用的问题
      • 方法区
  • 回收算法讲解
    • 标记 - 清除算法
    • 标记 - 复制算法
    • 标记 - 整理算法
  • 常用的垃圾回收器
    • Serial/Serial Old
    • ParNew( 负责收集新生代区域)
    • Parallel Scavenge
    • Parallel Old
    • CMS
      • CMS 负责收集老年代区域,它采用**标记-清除**算法。
    • G1
      • 运行步骤
    • 三色标记(解决或降低用户线程的停顿)
        • 原理流程
      • 最终标记和重新标记解决了什么?
        • 漏标
        • 多标
        • 读屏障、写屏障
        • CMS通过写屏障卡表解决
        • G1写屏障rset解决

回收哪个区域?

JVM GC只回收堆区和方法区内的基本类型数据和对象。

栈区的数据(仅指基本类型数据),在超出作用域后会自动出栈释放掉,所以其不在JVM GC的管理范围内。

关联面试题:fullgc会回收方法区(元空间)吗?

1.常量对象不再任何地方被引用的时候,这个常量可以被回收
2.无用类(堆中不存在该类的任何实例对象,加载该类的类加载器已经被回收,Class对象不在任何地方被引用)

怎么判断对象可以被回收了

对象不可达

GC Roots 作为起始节点,从这些节点开始,根据引用关系向下搜索,搜索过程的就是一条引用链,没有在这个链条上面的对象,也就是根节点通过引用链不可达到这个对象时,就认为这个对象是可以被回收的。

关联面试题:哪些对象可以作为 GC Root (两栈两方法)

  • 虚拟机栈中引用的对象
  • 本地方法栈中 JNI引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
public class StaticObj {
    public static Object obj = new Object();
    
    //...
}
public class ConstObj {
    public static final String STR = "hello";
    
    //...
}

JVM GC什么时候执行?

  • 老年代空间不足
  • 方法区空间不足
  • Eden区和s区不足
  • 手动触发gc

分代回收机制

弱分代假说:绝大多数对象都是朝生夕死的。
强分代假说:熬过越多次的垃圾回收的对象,就越难消亡

思考:假如eden区80m,老年代200m,一个对象90m?

老年代的担保机制,如果一个对象大于设定的值那么直接丢到老年代中。
除此之外,当存活的对象超过Survivor空间大小时,这些存活的对象会忽略年龄,直接进入老年代里。

各区域触发垃圾回收的类型与解释

  • Minor GC:只回收新生代区域。
  • Major GC:只回收老年代区域。只有CMS实现了MajorGC,所以在老年代里,触发GC,除了CMS和G1之外的其他收集器,大多数触发的其实是 Full GC
  • Full GC:回收整个堆区和方法区
  • Mixed GC:回收整个新生代和部分老年代。G1收集器实现了这个类型。

新生代

默认情况下,新生代(Young generation)、老年代(Old generation)所占空间比例为 1 : 2 。
包含1个伊甸园空间(Eden), 2个幸存者空间(Fron Survivor、To Survivor)
Eden : Fron : To = 8 : 1 : 1
适合使用标记-复制算法

新生代GC收集(类比倒水)

新创建的对象,是保存在伊甸园空间的(Eden)。那些经历多次GC依然存活的对象会经由幸存者空间(Survivor)转存到老年代空间(Old generation)

老年代(为什么老年代的回收耗时,比新生代更长呢)

1、老年代内存占比更大,所以理论上回收的时间也更长
2、老年代使用的是标记-整理算法,清理完成内存后,还得把存活的对象重新排序整理成连续的空间,成本更高

跨代引用的问题

卡表(Card Table)
每一个卡页,可能会包含N个存在跨区域引用的对象,只要存在跨区域引用的对象,这个卡页就会被标识为1。当GC发生的时候,就不需要扫描整个区域了,只需要把这些被标识为1的卡页加入对应区域的 GC Roots 里一起扫描即可。

方法区

之前引用的面试题已经说明过,这边再重新说明一次
1.常量对象不再任何地方被引用的时候,这个常量可以被回收
2.无用类(堆中不存在该类的任何实例对象,加载该类的类加载器已经被回收,Class对象不在任何地方被引用)

回收算法讲解

标记 - 清除算法

标记出所有存活的对象,再扫描整个空间中未被标记的对象直接回收。

标记 - 复制算法

把内存分成两块大小相同的空间(1 : 1),每次只使用其中一块,当使用中的这块内存用完了,就把存活的对象移动到另一块内存中,再把使用过的这块内存空间一次性清理掉。(依照eden区、survivor区思考)
缺点:这个做法虽然效率极高,但也浪费了一半的内存空间。

标记 - 整理算法

和标记-清除算法一样,先标记,但清除之前,会先进行整理,把所有存活的对象往内存空间的左边移动,然后清理掉存活对象边界以外的内存,即完成了清除的操作。

常用的垃圾回收器

Serial/Serial Old

一个单线程工作的收集器。在进行垃圾回收的时候,需要暂停所有的用户线程,直到回收结束。

ParNew( 负责收集新生代区域)

ParNew 就是 在Serial 收集器的基础之上,实现了它的多线程版本。

Parallel Scavenge

和 ParNew 很相似,都是新生代的收集器,支持多线程并行回收,也同样是使用标记-复制来作为回收算法。
区别:实现一个可控制吞吐量的垃圾收集器。

Parallel Old

Parallel Old 是 Parallel Scavenge 的老年代版本

CMS

CMS 负责收集老年代区域,它采用标记-清除算法。

  1. 初始标记
    STW,GC Root直接关联的对象
  2. 并发标记
    并发标记从GC Roots直接关联的对象开始,遍历整个引用链,这个阶段耗时较长,但用户线程可以和GC线程一起并发执行。
  3. 重新标记
    STW,重新标记就是修正用户线程继续运行,导致的变动的那一部分对象
  4. 并发清理

缺陷:
1.内存碎片。由于使用了 标记-清理 算法,回收结束后会产生大量不连续的内存空间,也就是内存碎片。
2.GC进行时会降低吞吐量。
3.浮动垃圾。CMS有两个阶段是可以用户线程和GC线程并发执行的,用户线程的继续执行自然会伴随垃圾的不断产生,这些就是浮动垃圾。这些垃圾只能等下次触发GC的时候才能清除了

G1

G1 收集器的设计理念是:实现一个停顿时间可控的低延迟垃圾收集器。

G1 依然遵循分代回收的设计理论,但它对堆(Java Heap)内存进行了重新布局,不再是简单的按照新生代、老年代分成两个固定大小的区域了,而是把堆区划分成很多个大小相同的区域(Region),新、老年代也不再固定在某个区域了,每一个Region都可以根据运行情况的需要,扮演Eden、Survivor、老年代区域、或者Humongous区域。

运行步骤

1.初始标记
只标记 GC Roots 能直接关联的对象
2.并发标记
从根节点(GC Root)开始,顺着引用链遍历整个堆,找出存活的对象。这个步骤耗时较长,但用户线程可以和GC线程并发执行。
3.最终标记
处理并发标记阶段,用户线程继续运行产生的引用变动,这个阶段需要暂停用户线程,支持并行处理。
4.筛选回收
计算出各个Region的回收价值和成本,再根据用户期望的停顿时间来决定要回收多少个Region。
回收使用的是复制算法,把需要回收的这些Region里存活的对象,复制到空闲的Region中,然后清理掉旧Region全部空间。

三色标记(解决或降低用户线程的停顿)

原理流程

初始标记
在这里插入图片描述
并发标记
在这里插入图片描述
在这里插入图片描述

此时黑色对象就是存活的对象,白色对象就是已消亡可回收的对象。

最终标记和重新标记解决了什么?

漏标

在这里插入图片描述
D此时所有引用已经扫描过,但是此时D->G,但是对于GC线程来说,是不知道这个引用的,就会产生漏标。

多标

在这里插入图片描述
D->E 引用断开,E、F、G不可达。

读屏障、写屏障

在读写前后,将变动节点记录下来(对象 G) 给记录下来。(可以想象成AOP)

CMS通过写屏障卡表解决

卡表是一个与Java堆大小相同的数组,每个元素记录着相应内存区域是否被修改。当用户线程修改了某个被标记的对象的指针时,就会由卡表中相应的条目被设置为“dirty”。垃圾收集器会检查卡表中所有“dirty”条目所对应的内存区域。

G1写屏障rset解决

Remembered Set(RSet),它是一种专门针对并发标记整理算法的优化,它能够更方便和高效地记录所有引用了老年代对象的新生代对象,避免了传统卡表方式在处理跨代引用时需要全局扫描卡表的缺点。
当某个Region的对象被修改时,处理这个Region的线程需要扫描该Region的RSet,找到其他Region中指向该Region的对象,

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

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

相关文章

pandas---文件读取与存储(csv、hdf、json、excel、sql)

数据大部分存在于文件当中,所以pandas会支持复杂的IO操作,pandas的API支持众多的文件格 式,如CSV、SQL、EXCEL、JSON、 HDF5。 1. csv文件 pandas.read_csv(filepath_or_buffer, sep ,, usecols ) filepath_or_buffer:文件路径 sep :…

简要介绍 | 强化学习:从原理到应用

注1:本文系“简要介绍”系列之一,仅从概念上对强化学习进行非常简要的介绍,不适合用于深入和详细的了解。 注2:"简要介绍"系列的所有创作均使用了AIGC工具辅助 强化学习:从原理到应用 1. 背景介绍 强化学习…

手撕学生管理系统超详解——【c++】

题目要求:设计一个学生成绩管理程序,实现按班级完成对学生成绩信息的录入和修改,并用文件保存。 实现按班级输出学生的成绩单;实现按学号和姓名进行查询,按平均成绩进行排序功能。 问题描述 该程序的目标是提供一个简单且易于使用…

scratch lenet(2): C语言实现图像直方图的计算

scratch lenet(2): C语言实现图像直方图的计算 1. 目的 用 C 语言实现 uint8 类型图像(单通道)的直方图计算。不涉及直方图均衡化。 2. 什么是图像直方图 2.1 统计得到图像直方图 通常是对于单通道的灰度图而言的。像素范围是 [0, 255], 统计每个像…

提高错误日志处理效率!使用Python和钉钉机器人实现自动告警聚合

1、背景 日志是非常重要的信息资源。它们记录了应用程序的运行状态、错误和异常情况,帮助我们了解系统的健康状况以及发现潜在的问题。为了高效地管理和分析日志数据,许多组织采用了Elasticsearch、Logstash和Kibana(ELK)堆栈作为…

Eclipse Krazo(Jakarta MVC)的使用

文章目录 背景Jakarta MVC规范Eclipse Krazo使用前的思考全局配置Controller示例返回View的三种写法View中用到的Model如何设值?View中如何获取Model中的值? 参数校验防止CSRFKrazo是如何实现的呢?如何生成csrf的token?如何校验cs…

开源赋能,决胜未来 — 参加原子全球开源峰会有感

目录 文章目录 目录前言开源决胜未来:闭源摧毁 UNIX,开源成就 Linux开源创新:软硬件协同,共建开源生态 前言 开源原子基金会作为国内首家开源基金会组织,由其主办的首届 “开放原子全球开源峰会” 也是第一次被冠以 “…

干货文:Mac 中 .bash_profile 和 .zshrc 的区别

如果你想在 Mac OS 中配置 MySQL 的环境变量,在 .zshrc 文件中添加如下内容: # 设置 mysql 的路径 export MYSQL_HOME/usr/local/mysql/bin# 将 MYSQL_HOME 添加到 PATH 中 export PATH$HOME/bin:/usr/local/bin:$MYSQL_HOME:$PATH# 解决需要 source 才…

硬件【9】详解二极管钳位电路

文章目录 1 概述1.1 正向钳位电路1.2 偏置正向钳位电路 1 概述 在之前的 二极管限幅电路 一文中,我们学习了二极管限幅电路,该电路可以削掉一部分信号,但不会影响剩余信号。今天,我们将学习另一种基于二极管的电路,该…

搭建环境【2】windows主机和ubuntu互传文件的4种方法

我的ubuntu系统是安装在 VMware 虚拟机中的,两者之间经常要互传文件,下面介绍4种常用的互传文件方法。 1. 共享文件夹方式互传 在虚拟机中需要开启共享文件夹的功能。首先虚拟机中的ubuntu要求是已经开机了的状态,然后进行设置:…

Vue2封装一个全局通知组件并发布到NPM

✍🏼作者:周棋洛,计算机学生 ♉星座:金牛座 🏠主页:点击查看更多 🌐关键:vue2 组件封装 npm发包 文章目录 1. 前言 🍃2. 我为什么要封装通知插件 ❓3. 初始化vue空项目 &…

B047-cms02-高级查询 删除 添加 修改

目录 高级查询页面准备下拉框显示文章类型ArticleController用jstl和el表达式取值展示 高级查询参数ArticleQuery 高级查询页面发送请求导入jquery.jdirk.js在jquery下引用绑定按钮发送请求高级查询sql 绑定删除事件绑定事件拿到标签id值准备模态框来自xmind弹出删除模态框绑定…

matlab不显示子图刻度并调整子图间距

matlab中在使用subplot函数画图时,尤其是做emd分解查看IMF时, 正常画图的代码及结果如下: figure for i 1:size(imf_norm,1)subplot(7,1,i)plot(imf_norm(i,:))ylabel(IMFstring(i)) end其中imf_norm为分解得到的imfs 效果图: …

python里apply用法_Python apply函数的用法

Python编程语言Python 是一种面向对象、解释型计算机程序设计语言,由Guido van Rossum于1989年底发明,第一个公开发行版发行于1991年。Python语法简洁而清晰,具有丰富和强大的类库。它常被昵称为胶水语言,它能够把用其他语言制作的…

HDL抽象等级 仿真模型 网表 delay speicfy与sdf

1.HDL 硬件描述语言 抽象分级 HDL这里主要说verilog 在描述硬件电路时分为三个抽象级别 行为级模型:主要用于test bench,着重系统行为和算法,不在于电路实现,不可综合(常用描述有initial,fork/join&#…

【MYSQL】MYSQL应用环境,系统特征,储存引擎,应用框架和索引功能的详细讲解

作者简介: 辭七七,目前大一,正在学习C/C,Java,Python等 作者主页: 七七的个人主页 文章收录专栏: 七七的闲谈 欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖&#x1f…

DINO-DETR匈牙利匹配与加噪过程学习记录

今天再来回顾一下DINO中匈牙利匹配与损失函数部分,该部分大致与DETR相似,却又略有不同。 为了查看数据方便,博主将num_query改为20,max_select值也为20。 匈牙利匹配过程 首先是数据送入匈牙利匹配中进行标签匹配过程了。 获取…

qt.qpa.plugin: Could not load the Qt platform plugin “xcb“ in

兄弟们看看是不是这个错: QObject::moveToThread: Current thread (0xe5205f0) is not the objects thread (0xa14d0f0). Cannot move to target thread (0xe5205f0)qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "/xxx/python3.…

Esp32+Blynk实现云端控制LED开灭

目录 环境配置依赖库安装blynk 基础设置 GPIO 点灯实验 环境配置 依赖库安装 参考 blynk 官方快速上手文档 如果要使用 blynk 提供的环境,我们就必须安装对应的库 选择基于 blynk 且适用于 ESP32 的库并安装到 arduino 上: blynk 基础设置 进入官网并且…

Question1:harbor登录成功,推送镜像失败

denied: requested access to the resource is denied 解决方案 查看用户的权限 Harbor 用户角色权限速查 系统级角色: Harbor 系统管理员:“Harbor 系统管理员”拥有最多的权限。除了上述权限外,“Harbor 系统管理员”还可以列出所有项目、…