JVM——垃圾回收器

目录

垃圾回收器

垃圾回收器的组合关系:

年轻代-Serial垃圾回收器:

老年代-SerialOld垃圾回收器:

年轻代-ParNew垃圾回收器:

老年代-CMS垃圾回收器:

年轻代-Parallel Scavenge:【JDK8默认】

老年代-Parallel Old垃圾回收算法[JDK8默认]

G1垃圾回收器:

总结:


垃圾回收器

  • 系统中的大部分对象,都是创建出来之后很快就不再使用可以被回收,比如订单数据返回给用户之后就可以释放了。
  • 老年代中会存放长期存活的对象,比如Spring的大部分Bean对象,在程序启动之后就不会被回收了
  • 在虚拟机的默认设置中,新生代大小要远小于老年代大小
问题 :为什么分代GC算法要把堆分为年轻代和老年代?【基本是3:7 通过配置启动中的VM来执行查看】
原因:
垃圾回收器的组合关系:
垃圾回收器是垃圾回收算法的具体实现
由于垃圾回收器分为年轻代和老年代,除了G1之外的其他垃圾回收器必须成组合进行使用
具体关系图如下:
年轻代-Serial垃圾回收器:
Serial是一种 单线程串行回收年轻代的垃圾回收器
回收年代和算法:年轻代、复制算法
优点:单CPU处理器下吞吐量非常出色
缺点:多CPU下吞吐量不如其他垃圾回收器,堆如果偏大会让用户线程处于长时间等待
适用场景:Java编写的客户端程序或者配置有限的场景。
老年代-SerialOld垃圾回收器:
SerialOld是Serial垃圾回收器的老年代版本,采用单线程串行回收
-XX:+UseSerialGC 新生代、老年代都是用串行回收器
年轻代-ParNew垃圾回收器:
ParNew垃圾回收器本质上是对Serial再多CPU下的优化,使用多线程进行垃圾回收
-XX:+UseparNewGC 新生代使用ParNew回收器,老年代使用串行回收器
老年代-CMS垃圾回收器
CMS垃圾回收器 关注的是系统的暂停时间,允许用户线程和垃圾回收线程再某些步骤中同时执行,减少了用户线程的等待时间。
参数:XX:+UseConcMarkSweepGC
CMS执行步骤
  1. 初始标记,用极短的时间标记处GC Roots能直接关联到的对象
  2. 并发标记,标记所有对象,用户线程不需要暂停【标记哪些对象需要回收,哪些不需要】
  3. 重新标记,由于并发标记阶段有些对象会发生了变化,存在错标、漏标等情况,需要重新标记【因为第二个阶段是并发执行的,所以需要对用户线程发生的变化进行处理】
  4. 并发编程,清理死亡的对象,用户线程不需要暂停。
CMS垃圾回收器存在的问题
  1. CMS使用了标记清除算法,在垃圾回收结束之后会出现大量的内存碎片,CMS会在FUll GC时进行碎片整理。这样会导致用户线程暂停,可以使用-XX:CMSFullGCsBeforeCompaction=N 参数 (默认为0) 调整N次Full GC之后再整理。
  2. 无法处理在并发清理过程中产生的“浮动垃圾”,不能做到完全的垃圾回收
  3. 如果老年代内存不足无法分配对象,CMS就会退化成Serial Old单线程回收老年代。【老年代内存不足是因为步骤二中无法处理并发清理过程中的“浮动垃圾”,并且这个时间就会特别长】
年轻代-Parallel Scavenge:【JDK8默认】
Parallel Scavenge是JDK8默认的年轻代垃圾回收器,多线程并行回收,关 注的是系统的吞吐量。具备自动调整堆内存的大小的特点、 可以手动设置最大垃圾回收时间和吞吐量、然后PS根据你设置的这两个参数来自动调整内存大小
吞吐量的计算公式: 吞吐量 = CPU在用户应用程序运行的时间 / (CPU在用户应用程序运行的时间 + CPU垃圾回收的时间)
参数:
老年代-Parallel Old垃圾回收算法[JDK8默认]
G1垃圾回收器:
JDK9之后默认的垃圾回收器是G1(Garbage First)垃圾回收器
Parallel Scavenge关注吞吐量,允许用户设置最大暂停时间,但是会减少年轻代可用空间的大小
CMS关注暂停时间,但是吞吐量方面会下降
而G1设计目标就是将上述两种垃圾回收器的优点融合:
  1. 支持巨大的堆空间回收,并具有较高的吞吐量。
  2. 支持多CPu并行垃圾回收
  3. 允许用户设置最大暂停时间
G1垃圾回收器有两种方式:
  1. 年轻代回收
  2. 混合回收
年轻代回收
回收Eden去和Survivor区中不用的对象。会导致STW,G1中可以通过参数-XX:MaxGCpauseMillis=n (默认是200)设置每次垃圾回收是的最大暂停时间毫秒数,G1垃圾回收器会尽可能地保证暂停的时间
执行流程
  1. 新创建的对象会存放在Eden区。当G1判断年轻代区不足(max默认为60%),无法分配对象时需要回收时会执行Young GC。
  2. 标记出Eden和Survivor区域中的存活对象
  3. 根据最大的暂停时间来选择某写区域将存活对象复制到一个新的Survivor区中(年龄+1),清空这些区域。
    1. G1在进行Young GC的过程中回去记录每次垃圾回收时灭个Eden区和Survivor区的平均耗时,以作为下次回收时的参考依据。这样就可以根据配置的最大暂停时间计算出本次回收最多能回收多少个Region区域了,比如-XX:MaxGCPauseMillis=n(默认为200),每个Region回收耗时40ms,那么这次回收最多只能回收4个Region。
  4. 后续的Young GC时与之前相同,只不过Survivor区中存活对象会被搬运到另一个Survivor区。
  5. 当某个存活对象的年龄到达阈值(默认15),将被放入老年代
  6. 部分对象如果大小超过Region的一半,会直接放入老年代,这类老年代被称为Humongous区,比如对内存是4G,每个Region时2M,只要一个大对象超过了1M就会被放入Humongous区,如果对象过大会横跨多个Region。
  7. 多次回收之后,会出现很多Old老年代区,此时总堆占有率达到阈值时(-XX:IniniatingHeapOccupancuPercent 默认45%)会触发混合回收MixedGC。回收所有年轻代和部分老年代的对象以及大对象区。采用复制算法来完成
混合回收执行流程:
  • 混合回收分为:初始标记并发标记最终标记并发清理
  • G1对老年代的清理会选择存活度最低的区域来进行回收,这样可以保证回收效率最高,这也是G1名称的由来。
  • G1对老年代的清理会选择存活度最低的区域来进行回收,这样可以保证回收效率最高,这也是G1(Garbage First)名称的由来
  • 最后清理阶段使用复制算法,不会产生内存碎片。
FULL GC
注意:如果清理过程中发现没有足够的空Region存放转移的对象,会出现Full GC 单线程执行标记-整理算法,此时会导致用户线程的暂停。所以尽量保证应该用的堆内存有一定多余的空间。
G1-Garbage First垃圾回收器
参数1:-XX:+UseG1GC 打开G1的开关,JDK9之后默认不需要打开
参数2:-XX:MaxGCPauseMillis=毫秒值最大暂停的时间
总结:
垃圾回收器的组合关系虽然很多,但是针对几个特定的版本,比较好的组合选择如下:
  • JDK8之前:
    • ParNew + CMS (关注暂停时间)、Parallel Scavenge + Parallel Old(关注吞吐量)、G1(JDK8之前不建议,较大堆并且关注暂停时间)
  • JDK9之后:
    • G1
  1. Java中有哪几块内存需要进行垃圾回收?
    1. 对于线程不共享的部分:程序计数器、java虚拟机栈、本地方法栈,跟随线程的生命周期随着线程回收而回收
    2. 对于线程共享的部分:方法区一般不需要回收,堆由垃圾回收器进行回收
  2. 有哪几种常见的引用类型?
    1. 强引用,最常见的引用方式,由可达性分析算法来判断【通过GCRoot可以找到的就是强引用】
    2. 软引用,对象在没有强引用的情况下,内存不足时会回收
    3. 弱引用,对象在没有强引用情况下,会直接回收
    4. 虚引用,通过虚引用知道对象被回收了
    5. 终结器引用,对象回收时可以自救,不建议使用
  3. 有哪几种常见的垃圾回收算法?
    1. 标记-清除算法:标记之后再清除,容易产生内存碎片
    2. 复制算法:从一块区域复制到另一块区域,容易造成只能使用一部分内存
    3. 标记-整理算法:标记之后将存活的对象推到一边对象会移动,效率不高
    4. 分代GC:将内存区域划分为年轻代、幸存者区、老年代进行回收,可以使用多种回收算法
  4. 常见的垃圾回收器有哪些?
    1. Serial + Serial Old:单线程回收,主要适用于单核CPU场
    2. parNew + CMS:暂停时间较短,适用于与用户交互的部分
    3. Parallel Scavenge + parallel Old:吞吐量高,适用于后台进行大量数据操作
    4. G1:适用于较大的堆,具有可控的暂停时间

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

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

相关文章

数据库第三次作业

第一题: 学生表:Student (Sno, Sname, Ssex , Sage, Sdept) 学号,姓名,性别,年龄,所在系 Sno为主键 课程表:Course (Cno, Cname,) 课程号,课程名 Cno为主键 学生选课表:S…

类与对象(OOP)

类(Class) 类是对象的模板或蓝图,用来描述对象的属性和行为。 动态与静态是同一张图像,最终效果也是相同 类的组成分别由: 属性(成员变量):描述对象的状态。 方法(成员方法):描述对象的行为。 构造函数:用于创建对象…

C++ 的 get 和 get_if

1 std::get() 1.1 用于 std::pair 和 std::tuple ​ 在介绍 std::pair 和 std::tuple 的时候已经介绍过如何用 std::get() 获取对应位置上的值&#xff0c;用法大致如此&#xff1a; std::pair<int, double> p(42, 5.1); assert(std::get<0>(p) p.first); std:…

全面理解-什么是尾递归优化?

尾递归&#xff08;Tail Recursion&#xff09; 是一种特殊的递归形式&#xff0c;其特点是递归调用是函数的 最后一步操作。尾递归可以被编译器优化为迭代形式&#xff0c;从而避免递归调用带来的栈溢出问题&#xff0c;并提升性能。 以下是尾递归的详细说明和优化原理&#…

大脑神经网络与机器神经网络的区别

大脑神经网络(生物神经网络)与机器神经网络(人工神经网络,ANN)虽然名称相似,但在结构、功能、学习机制等方面存在显著差异。以下是两者的主要区别: 1. 基础结构与组成 大脑神经网络: 由 生物神经元(约860亿个)通过突触连接形成动态网络。 神经元通过电化学信号(动作…

haproxy详解笔记

一、概述 HAProxy&#xff08;High Availability Proxy&#xff09;是一款开源的高性能 TCP/HTTP 负载均衡器和代理服务器&#xff0c;用于将大量并发连接分发到多个服务器上&#xff0c;从而提高系统的可用性和负载能力。它支持多种负载均衡算法&#xff0c;能够根据服务器的…

选购电子实验记录本ELN时,怎么评估?

企业全面数字化的趋势愈发明显&#xff0c;实验室数字化也从“要不要实施”&#xff0c;变为“如何开始实施”、“如何避免实施失败”的紧迫状态。不实施数字化的企业&#xff0c;将迅速落后于同类企业&#xff0c;逐渐被市场淘汰。 其中&#xff0c;电子实验记录本&#xff0…

前端开发工程中如何利用DeepSeek提升工作效率:实战案例与策略解析

目录 引言DeepSeek的核心功能与技术优势实际项目场景与问题分析 3.1 电商网站性能优化3.2 企业级管理系统代码质量提升3.3 跨端应用开发效率优化DeepSeek解决问题的策略与手段 4.1 代码智能分析与重构4.2 性能瓶颈定位与优化建议4.3 团队协作与知识沉淀代码样例与操作流程数据驱…

Linux探秘坊-------7.进程概念

1.进程概念 1.冯诺依曼体系结构 输⼊单元&#xff1a;包括键盘,⿏标&#xff0c;扫描仪,写板等中央处理器(CPU)&#xff1a;含有运算器和控制器等输出单元&#xff1a;显⽰器&#xff0c;打印机等这⾥的存储器指的是内存 ⼀句话&#xff0c;所有设备都 只能直接和内存打交道。…

python专栏导读

由于本人非python工程师&#xff0c;是在自学python&#xff0c;所以本专栏的内容会显得很基础&#xff0c;甚至有些内容在python工程师看来实在太过于简单&#xff0c;在此清楚嘲笑&#xff0c;因为毕竟每个人都是从不懂、从基础开始的。 本篇作为导读和目录形式存在&#xf…

docker 部署nginx,nginx 504

遇到问题 原因&#xff1a; 因为用的docker 部署nginx, docker 应用与服务之间的端口未开放&#xff0c;导致访问不到服务。

每日一题-斐波那契数列和跳台阶

斐波那契数列和跳台阶 斐波那契数列题目描述斐波那契数列的定义&#xff1a;数据范围&#xff1a;题目要求&#xff1a; 输入描述&#xff1a;输出描述&#xff1a;示例示例 1&#xff1a;示例 2&#xff1a;示例 3&#xff1a; 解法1. 递归解法代码解释&#xff1a; 2. 动态规…

MySQL 联合索引的最左匹配原则

环境&#xff1a;MySQL 版本&#xff1a;8.0.27 执行计划基础知识 possible_keys&#xff1a;可能用到的索引 key&#xff1a;实际用到的索引 type: ref&#xff1a;当通过普通的二级索引列与常量进行等值匹配的方式 询某个表时const&#xff1a;当我们根据主键或者唯一得…

算法07-滑动窗⼝算法

滑动窗口算法&#xff08;Sliding Window&#xff09; 一、详细讲解 A、一句话总结 滑动窗口算法是一种通过维护一个动态窗口来解决问题的技巧&#xff0c;窗口在数据上“滑动”&#xff0c;逐步找到最优解。 B、核心思想 想象你在看一列火车&#xff0c;火车窗口只能看到一…

docker安装mongo,导入、导出数据

1、docker安装mongo docker pull mongo docker run -d -p 27017:27017 --name mongodb mongodocker update mongodb --restartalways ## 开机自启动-d&#xff1a;表示以后台模式运行容器。 -p 27017:27017&#xff1a;将容器内部的 MongoDB 默认端口 27017 映射到宿主机的 27…

GB300加速推进,RTX 50显卡芯片量产延后,NVIDIA面临新的挑战与机遇

野村分析师Anne Lee在2月12日的报告中表示&#xff0c;2025年全球服务器营收将同比增长46%&#xff0c;2026年增长22%。其中&#xff0c;AI服务器营收预计在2025年和2026年分别增长75%和31%。这些预测与近期美国主要云服务提供商(CSP)上调的资本支出指引基本一致。 GB300加速推…

[NOIP2011 普及组] 统计单词数 题解

&#xff08;一&#xff09;读懂题目 关键词&#xff1a;查找单词 方法&#xff1a;枚举&#xff08;二&#xff09;分析算法时间复杂度和空间复杂度 算法&#xff1a;枚举 时间复杂度&#xff1a;O(n) 空间复杂度&#xff1a;O(n)&#xff08;三&#xff09;代码实现 代码如…

深入解析 ipoib_intf_init 函数中的 netdev_ops 设置逻辑

在 Linux 内核的网络设备驱动开发中,net_device_ops 是一个至关重要的结构体,它定义了网络设备的各种操作函数指针,决定了网络设备的行为和功能。本文将深入解析 ipoib_intf_init 函数中关于 dev->netdev_ops 和 priv->rn_ops 的设置逻辑,帮助读者理解其设计动机和实…

leetcode_1760 袋子里最少数目的球

1. 题意 给定一个数组&#xff0c;和一个最多次操作次数。每次操作可以将数组中的一个数 x x x分成两个数 t x − t t\quad x-t tx−t。问 m a x O p e r a t i o n C n t maxOperationCnt maxOperationCnt次操作后&#xff0c;数组中最大的数最小的值是多少。 2. 题解 这个…

TDengine 性能测试工具 taosBenchmark

简介工具获取运行 无参数模式命令行模式配置文件模式 命令行参数配置文件参数 通用配置参数写入配置参数 数据库相关超级表相关标签列与数据列写入行为相关 查询配置参数 执行指定查询语句查询超级表 订阅配置参数数据类型对照表 配置文件示例 写入 JSON 示例查询 JSON 示例订阅…