JVM垃圾回收

如何确定垃圾

对堆垃圾回收前的第一步就是要判断哪些对象已经死亡(即不能再被任何途径使用的对象)

引用计数法

这个方法就是为对象添加计数器来标识引用个数,计数器为 0 的对象就是不可能再被使用的。但是这种方法存在循环引用问题,目前并未被使用。

 可达性分析算法

这个算法的基本思想就是通过一系列的称为 “GC Roots” 的对象作为起点,从这些节点开始向下搜索,节点所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连的话,则证明此对象是不可用的,需要被回收。

那么关键是明确哪些是GC Roots:(咱们从头到尾说一次Java垃圾回收 | Java程序员进阶之路)

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈中 JNI(即一般说的 Native 方法)引用的对象

垃圾回收算法

那么知道了内存中哪些对象是垃圾对象,怎么回收呢

标记-清除算法

顾名思义,就是标记垃圾对象,然后清除

标记-清除算法

 复制算法

它可以将内存分为大小相同的两块,每次使用其中的一块。当这一块的内存使用完后,就将还存活的对象复制到另一块去,然后再把使用的空间一次清理掉。这样就使每次的内存回收都是对内存区间的一半进行回收。

复制算法

 问题:

实际使用的空间只有一半; 复制操作会带来开销;

标记-整理算法

仍然是先标记,然后会让所有存活的对象向一端移动,然后直接清理掉端边界以外的内存。

标记-整理算法

 分代收集算法

只是根据对象存活周期的不同将内存分为几块。一般将 Java 堆分为新生代和老年代,这样我们就可以根据各个年代的特点选择合适的垃圾收集算法。

比如在新生代中,每次收集都会有大量对象死去,所以可以选择”标记-复制“算法,只需要付出少量对象的复制成本就可以完成每次垃圾收集。而老年代的对象存活几率是比较高的,而且没有额外的空间对它进行分配担保,所以我们必须选择“标记-清除”或“标记-整理”算法进行垃圾收集。

垃圾回收器

上面介绍的都是理论算法,实际jvm会实现很多垃圾回收器,以供不同场合使用。

JDK 默认垃圾收集器(使用 java -XX:+PrintCommandLineFlags -version 命令查看):

JDK 8:Parallel Scavenge(新生代)+ Parallel Old(老年代)
JDK 9 ~ JDK20: G1

CMS 收集器

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。它非常符合在注重用户体验的应用上使用。

CMS(Concurrent Mark Sweep)收集器是 HotSpot 虚拟机第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程(基本上)同时工作。

从名字中的Mark Sweep这两个词可以看出,CMS 收集器是一种 “标记-清除”算法实现的,它的运作过程相比于前面几种垃圾收集器来说更加复杂一些。整个过程分为四个步骤:

初始标记: 暂停所有的其他线程,并记录下直接与 root 相连的对象,速度很快 ;
并发标记: 同时开启 GC 和用户线程,用一个闭包结构去记录可达对象。但在这个阶段结束,这个闭包结构并不能保证包含当前所有的可达对象。因为用户线程可能会不断的更新引用域,所以 GC 线程无法保证可达性分析的实时性。所以这个算法里会跟踪记录这些发生引用更新的地方。
重新标记: 重新标记阶段就是为了修正并发标记期间因为用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段的时间稍长,远远比并发标记阶段时间短
并发清除: 开启用户线程,同时 GC 线程开始对未标记的区域做清扫。

CMS 收集器

 


从它的名字就可以看出它是一款优秀的垃圾收集器,主要优点:并发收集、低停顿。但是它有下面三个明显的缺点:

对 CPU 资源敏感;
无法处理浮动垃圾;
它使用的回收算法-“标记-清除”算法会导致收集结束时会有大量空间碎片产生。
 

G1 收集器

G1 (Garbage-First) 是一款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器. 以极高概率满足 GC 停顿时间要求的同时,还具备高吞吐量性能特征.

被视为 JDK1.7 中 HotSpot 虚拟机的一个重要进化特征。它具备以下特点:

  • 并行与并发:G1 能充分利用 CPU、多核环境下的硬件优势,使用多个 CPU(CPU 或者 CPU 核心)来缩短 Stop-The-World 停顿时间。部分其他收集器原本需要停顿 Java 线程执行的 GC 动作,G1 收集器仍然可以通过并发的方式让 java 程序继续执行。
  • 分代收集:虽然 G1 可以不需要其他收集器配合就能独立管理整个 GC 堆,但是还是保留了分代的概念。
  • 空间整合:与 CMS 的“标记-清除”算法不同,G1 从整体来看是基于“标记-整理”算法实现的收集器;从局部上来看是基于“标记-复制”算法实现的。
  • 可预测的停顿:这是 G1 相对于 CMS 的另一个大优势,降低停顿时间是 G1 和 CMS 共同的关注点,但 G1 除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为 M 毫秒的时间片段内,消耗在垃圾收集上的时间不得超过 N 毫秒。

G1 收集器的运作大致分为以下几个步骤:

  • 初始标记
  • 并发标记
  • 最终标记
  • 筛选回收

G1 收集器

G1 收集器

G1 收集器在后台维护了一个优先列表,每次根据允许的收集时间,优先选择回收价值最大的 Region(这也就是它的名字 Garbage-First 的由来) 。这种使用 Region 划分内存空间以及有优先级的区域回收方式,保证了 G1 收集器在有限时间内可以尽可能高的收集效率(把内存化整为零)。

 

内存分配和回收的原则

对象优先在 Eden 区分配

大部分对象都是“朝生晚死”,大多数情况下,对象会在新生代 Eden 区中进行分配。当 Eden 区没有足够空间进行分配时,虚拟机将发起一次 Minor GC。

长期存活的对象将进入老年代

既然虚拟机采用了分代收集的思想来管理内存,那么内存回收时就必须能识别哪些对象应放在新生代,哪些对象应放在老年代中。为了做到这一点,虚拟机给每个对象一个对象年龄(Age)计数器。

大部分情况,对象都会首先在 Eden 区域分配。如果对象在 Eden 出生并经过第一次 Minor GC 后仍然能够存活,并且能被 Survivor 容纳的话,将被移动到 Survivor 空间(s0 或者 s1)中,并将对象年龄设为 1(Eden 区->Survivor 区后对象的初始年龄变为 1)。

对象在 Survivor 中每熬过一次 MinorGC,年龄就增加 1 岁,当它的年龄增加到一定程度(默认为 15 岁),就会被晋升到老年代中。对象晋升到老年代的年龄阈值,可以通过参数 -XX:MaxTenuringThreshold 来设置。

大对象进入老年代

大对象就是需要大量连续内存空间的对象(比如:字符串、数组)。

大对象直接进入老年代的行为是由虚拟机动态决定的,它与具体使用的垃圾回收器和相关参数有关。大对象直接进入老年代是一种优化策略,旨在避免将大对象放入新生代,从而减少新生代的垃圾回收频率和成本。

  • G1垃圾回收器会根据-XX:G1HeapRegionSize参数设置的堆区域大小和-XX:G1MixedGCLiveThresholdPercent参数设置的阈值,来决定哪些对象会直接进入老年代。
  • Parallel Scavenge垃圾回收器中,默认情况下,并没有一个固定的阈值(XX:ThresholdTolerance是动态调整的)来决定何时直接在老年代分配大对象。而是由虚拟机根据当前的堆内存情况和历史数据动态决定。

常见面试题:

  • 如何判断对象是否死亡(两种方法)。
  • 简单的介绍一下强引用、软引用、弱引用、虚引用(虚引用与软引用和弱引用的区别、使用软引用能带来的好处)。
  • 如何判断一个常量是废弃常量
  • 如何判断一个类是无用的类
  • 垃圾收集有哪些算法,各自的特点?
  • HotSpot 为什么要分为新生代和老年代?
  • 常见的垃圾回收器有哪些?
  • 介绍一下 CMS,G1 收集器。
  • Minor Gc 和 Full GC 有什么不同呢?

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

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

相关文章

布谷鸟配音:一站式配音软件

这是一款智能语音合成软件,可以快速将文字转换成语音,拥有多种真人模拟发音,可以选择不同男声、女声、童声,以及四川话、粤语等中文方言和外语配音,并且可对语速、语调、节奏、数字读法、多音字、背景音等进行全方位设…

less、sass的使用及其区别

CSS预处理器 CSS 预处理器是一种扩展了原生 CSS 的工具,它们添加了一些编程语言的特性,以便更有效地编写、组织和维护样式代码。预处理器允许开发者使用变量、嵌套、函数、混合等功能,从而使 CSS 更具可读性、可维护性和重用性,特…

学习笔记整理-JS-01-语法与变量

文章目录 一、语法与变量1. 初识JavaScript2. JavaScript的历史3. JavaScript与ECMAScript的关系4. JavaScript的体系5. JavaScript的语言风格和特性 二、语法1. JavaScript的书写位置2. 认识输出语句3. REPL环境,交互式解析器4. 变量是什么5. 重点内容 一、语法与变…

使用python快速搭建HTTP服务实现局域网网页浏览或文件传输

1.使用命令行(CMD)来快速搭建一个HTTP服务器 你可以借助Python的http.server模块。以下是在命令行中使用Python快速搭建HTTP服务器的步骤: 打开命令提示符(CMD)。 进入你想要共享文件的目录。使用 cd 命令来切换到目…

二、编写第一个 Spring MVC 程序

文章目录 一、编写第一个 Spring MVC 程序 一、编写第一个 Spring MVC 程序 代码示例 创建 maven 项目&#xff0c;以此项目为父项目&#xff0c;在父项目的 pom.xml 中导入相关依赖 <dependencies><dependency><groupId>junit</groupId><artifactI…

分支和循环语句(2)(C语言)

目录 do...while()循环 do语句的语法 do语句的特点 do while循环中的break和continue 练习 goto语句 do...while()循环 do语句的语法 do 循环语句; while(表达式); do语句的特点 循环至少执行一次&#xff0c;使用的场景有限&#xff0c;所以不是经常使用。 #inc…

【uniapp】uniapp自动导入自定义组件和设置分包:

文章目录 一、自动导入自定义组件&#xff1a;二、设置分包和预加载&#xff1a; 一、自动导入自定义组件&#xff1a; 【Volar 官网】https://github.com/vuejs/language-tools 二、设置分包和预加载&#xff1a; 【官方文档】https://uniapp.dcloud.net.cn/collocation…

【服务平台】Rancher运行和管理Docker和Kubernetes,提供管理生产中的容器所需的整个软件堆栈

Rancher是一个开源软件平台&#xff0c;使组织能够在生产中运行和管理Docker和Kubernetes。使用Rancher&#xff0c;组织不再需要使用一套独特的开源技术从头开始构建容器服务平台。Rancher提供了管理生产中的容器所需的整个软件堆栈。  完整软件堆栈 Rancher是供采用容器的团…

idea添加作者信息

idea添加作者信息 自定义作者信息idea添加作者信息自定义作者信息 自定义作者信息 idea添加作者信息 在idea中&#xff0c;经常会有这些波浪纹提示&#xff0c;放在上面之后会提示添加作者信息,点击添加作者信息后&#xff0c;但是不是自己想要的 这里提取的话好像没什么办法…

JavaWeb课程学习--Day01

HTML 建立css文件&#xff1a; css使用方式&#xff1a; <span>...</span>无语意包裹标签 css中的三种选择器&#xff1a; 注意&#xff1a;播放视音频时要留出播放空间 盒子模型&#xff1a; 表格标签&#xff1a; 以上表格&#xff1a; 表单标签&#xff1a; 表…

分布式 - 服务器Nginx:一小时入门系列之动静分离

文章目录 1. 动静分离的好处2. 分离静态文件3. 修改 Nginx 配置文件4. location 命令修饰符优先级 1. 动静分离的好处 Apache Tocmat 严格来说是一款java EE服务器&#xff0c;主要是用来处理 servlet请求。处理css、js、图片这些静态文件的IO性能不够好&#xff0c;因此&…

ROS学习--HelloWorld的实现(C++)

1.创建工作空间并初始化 mkdir -p 自定义空间名称/src cd 自定义空间名称 catkin_make上述命令&#xff0c;首先会创建一个工作空间以及一个 src 子目录&#xff0c;然后再进入工作空间调用 catkin_make命令编译。 2.进入 src 创建 ros 包并添加依赖 cd src catkin_create_pk…

苏纷享首届生态人脉会成功举办,纷享销客助力伙伴共同发展

近日&#xff0c;纷享销客&苏纷享成功举办了首届生态人脉会&#xff0c;该活动于8月3日下午在苏州东方之门举行。本次会议汇聚了来自近20家企业的销售精英&#xff0c;包括金蝶、泛微、夏谷、蚂蚁分工、创享、黑湖智造等众多知名企业。会议秉持着“建立生态、共同发展、深耕…

时间复杂度与空间复杂度的详解

目录 1.时间复杂度 2.时间复杂度计算例题 3.空间复杂度 1.时间复杂度 算法中的基本操作的执行次数&#xff0c;为算法的时间复杂度。 如何表达 时间复杂度&#xff1f; 大O的渐进表示法 实际中我们计算时间复杂度时&#xff0c;我们其实并不一定要计算精确的执行次数&#xf…

ArcGIS Pro暨基础入门、制图、空间分析、影像分析、三维建模、空间统计分析与建模、python融合、案例应用

GIS是利用电子计算机及其外部设备&#xff0c;采集、存储、分析和描述整个或部分地球表面与空间信息系统。简单地讲&#xff0c;它是在一定的地域内&#xff0c;将地理空间信息和 一些与该地域地理信息相关的属性信息结合起来&#xff0c;达到对地理和属性信息的综合管理。GIS的…

【数据结构】树和二叉树

一、树的概念及结构 1、树的概念 树 是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因 为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。 有一个特殊的结点&a…

mysql8.0.3集群搭建

下载mysql安装包&#xff1a; https://dev.mysql.com/downloads/mysql/5.7.html#downloads 准备环境 1、准备三台服务器并设置hosts 192.168.236.143 mysql1 192.168.236.144 mysql2 192.168.236.145 mysql32、设置免密登陆 #生成秘钥 ssh-keygen -t rsa #一直按Enter即可…

php从静态资源到动态内容

1、从HTML到PHP demo.php:后缀由html直接改为php,实际上当前页面已经变成了动态的php应用程序脚本 demo.php: 允许通过<?php ... ?>标签,添加php代码到当前脚本中 php标签内部代码由php.exe解释, php标签之外的代码原样输出,仍由web服务器解析 <!DOCTYPE html>…

MySQL数据库基础语法

一&#xff0c;数据库操作 数据库中不区分大小写&#xff01;&#xff01;&#xff01; 1.1 显示数据库 show databases ; 如图&#xff1a; 1.2 创建数据库 create database [ if not exists ]数据库名 ; 如图&#xff1a; 1.3 使用数据库 use 数据库名 &#xff1b; 如图&a…

8月13日,每日信息差

1、600余家互联网企业发出倡议&#xff1a;积极维护防汛救灾网络秩序、截至目前&#xff0c;包括百度、微博、抖音、快手、小红书、哔哩哔哩、阿里、腾讯等8家超大型互联网平台在内的600余家企业发出倡议书&#xff0c;唱响了万众一心、聚力救灾救援的网上主旋律 2、苏州调整耗…