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

03垃圾回收篇(D3_垃圾收集器的选择及相关参数)

目录

学习前言

一、收集器的选择

二、GC日志参数

三、垃圾收集相关的常用参数

四、内存分配与回收策略

1. 对象优先在Eden分配

2. 大对象直接进入老年代

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

4. 动态对象年龄判定

5. 空间分配担保


学习前言

本章主要学习垃圾收集器的选择及相关参数

在实际生产环境上应该如何选择垃圾收集器?相关参数如何设置?

这里只考虑OpenJDK/OracleJDK的HotSpot虚拟机上的垃圾收集器。

没有将Azul和OpenJ9的垃圾收集器加入选择范围,因为不了解。

一、收集器的选择

考虑垃圾收集器的选择时,需要考虑以下事项:

  1. 对于不可能三角(内存占用/吞吐量/延迟),应用的主要功能更关注什么?比如一个OLAP系统,它的大部分功能是各种数据分析和运算,目标是尽快完成计算任务给出结果,那么吞吐量就是主要关注点。而一个OLTP系统,它需要与用户频繁交互,用户频繁地通过页面操作录入数据,那么延迟就是主要关注点。而如果是一个客户端应用或者嵌入式应用,那么内存占用就是主要关注点。
  2. 应用运行的基础设施如何?包括但不限于CPU核数,内存大小?操作系统是Linux还是Windows等等。
  3. 使用的JDK是什么版本?9之前还是9以后?

简单列一个表格,可以参考该表格选择垃圾收集器:

垃圾收集器

关注点

硬件资源

操作系统

JDK版本

优势

劣势

ZGC

低延迟

大内存,很多核

64位操作系统

JDK15以上

延迟真低

需要足够的JVM调试能力;不分代,连续高湾大量内存分配时只能增加堆内存。

Shenandoah

低延迟

大内存,很多核

-

openJDK15以上

延迟很低

需要足够的JNM调试能力;没有ZGC延迅低。

G1

低延迟

4G以上内存,多核

-

JDK9以上

延迟相对较低,技术成熟

内存占用相对其他经典GC较多,延迟低延迟GC受高:

ParNew*CMS

低延迟

4G以下内存,多核

-

JDK9之前

延迟相对较低,技术成熟

已经被抛弃,更大的堆内存比不上G1

Parallel(Scavenge*Old)

吞吐量

-

-

-

吞吐量高

延迟较高

Serial*Serial Old

内存占用

-

-

-

内存占用低,CPU负荷低

延迟高,香吐低

简单总结一下就是,主流的,就做一个普通的JavaWeb,或者微服务中的后台服务,

与用户交互较多,那就根据Java版本来,不是 G1 就是 ParNew+CMS:

  • Java版本在9及9以上,那就无脑选择G1,默认即可;
  • Java版本还是8甚至更老,那就ParNew+CMS;

有点追求的,根据情况来:

  • 有足够的JVM调优能力,且对低延迟有追求,可以尝试ZGC或Shenandoah;
  • 主要做后台单纯数据运算的,比如OLAP,可以尝试Parallel(Scavenge+Old);
  • C/S架构的客户端应用,或者嵌入式应用,可以尝试 Serial+Serail Old。

二、GC日志参数

Java9之前,HotSpot没有统一日志框架,参数比较混乱;Java9之后,所有日志功能都归纳到了 -

Xlog 参数上。

Java9的JVM日志使用方式

-Xlog[:[selector][:[output][:[decorators][:output-options]]]]

说明:

  • selector:选择器,由标签tag和日志级别level组成。标签是功能模块,它指定输出哪个功能模块的日志,GC日志的话,标签就是gc;日志级别从低到高有:Trace、Debug、Info、Warning、Error、Off。
  • decorators:修饰器,指定每行日志的额外输出内容,包括:time,当前时间戳;uptime,VM启动到现在的秒数;timemillis,当前时间毫秒数;uptimemillis,VM启动到现在的毫秒数;timenanos,当前时间纳秒数;uptimenanos,VM启动到现在的纳秒数;pid,进程ID;tid,线程ID;level,日志级别;tags,日志标签。默认是uptime、level和tags。

参考:Java9前后GC相关日志参数对比

功能

Java9及之后

Java9之前

查看GC基本信息

-Xlog;gc

-XX:+PrintGC

查看GC详细信息

-X-log:gc*

-XX:+PrintGCDetails

查看GC前后空间变化

-Xlog:gc+heap=debug

-XX:+PrintHeapAtGC

查看GC中并发时间和停顿时

-Xlog:safepoint

-XX:+Print-GCApplicationConcurrentTime 和

-XX:+PrintGcApplicationstoppedTime

查看GC自适应调节信息

-Xlog:gc+ergo*=trace

-XX:+PrintAdaptive-SizePolicy

查看GC后剩余对象年龄分布

-Xlog:gc+age=trace

-XX:+PrintTenuring-Distribution

还有一个 -verbose:gc 参数,功能与 -Xlog:gc 以及 -XX:+PrintGC 一样。

Java8的 GC 日志的查看,请参考以前的文章:

java8添加并查看GC日志(ParNew+CMS)

三、垃圾收集相关的常用参数

四、内存分配与回收策略

Java技术体系的自动内存管理,最根本的目标是自动化地解决两个问题:自动给对象分配内存以及

自动回收分配给对象的内存。

1. 对象优先在Eden分配

大多数情况下,对象在新生代·Eden区中分配。

当Eden区没有足够空间进行分配时,虚拟机将发起 一次Minor GC。

HotSpot虚拟机提供了-XX:+PrintGCDetails这个收集器日志参数,告诉虚拟机在发生垃圾收集行

为时打印内存回收日志,并且在进程退出的时候输出当前的内存各区域分配情况。

2. 大对象直接进入老年代

大对象就是指需要大量连续内存空间的Java对象,最典型的大对象便是那种很长的字符串,或者元

素数量很庞大的数组,例如:创建一个典型的大对象byte[]数组。

在Java虚拟机中要避免大对象的原因是,在分配空间时,它容易 导致内存明明还有不少空间时就

提前触发垃圾收集,以获取足够的连续空间才能安置好它们,而当复制对象时,大对象就意味着高

额的内存复制开销。

HotSpot虚拟机提供了-XX:PretenureSizeThreshold参数,指定大于该设置值的对象直接在老年代

分配,这样做的目的就是避免在Eden区及两个Survivor区 之间来回复制,产生大量的内存复制操

作。

-XX:PretenureSizeThreshold参数只对Serial和ParNew两款新生代收集器有效,HotSpot的其他

新生代收集器,如Parallel Scavenge并不支持这个参数,如果必须使用此参数进行调优,可考虑

ParNew加CMS的收集器组合。

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

HotSpot虚拟机中多数收集器都采用了分代收集来管理堆内存,那内存回收时就必须能决策哪些存

活对象应当放在新生代,哪些存活对象放在老年代中,为做到这点,虚拟机给每个对象定义了一个

对象年龄(Age)计数器,存储在对象头中。

对象通常在Eden区里诞生,如果经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,

该对象会被移动到Survivor空间中,并且将其对象年龄设为1岁,对象在Survivor区中每熬过一次

Minor GC,年龄就增加1岁,当它的年龄增加到一定程 度(默认为15),就会被晋升到老年代

中。

对象晋升老年代的年龄阈值,可以通过参数-XX:MaxTenuringThreshold设置。

4. 动态对象年龄判定

为了能更好地适应不同程序的内存状况,HotSpot虚拟机并不是永远要求对象的年龄必须达到XX:

MaxTenuringThreshold才能晋升老年代,如果在Survivor空间中相同年龄所有对象大小的总和大于

Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到-XX:

MaxTenuringThreshold中要求的年龄。

5. 空间分配担保

在发生Minor GC之前,虚拟机必须先检查老年代最大可用的连续空间是否大于新生代所有对象总

空间,如果这个条件成立,那这一次Minor GC可以确保是安全的,如果不成立,则虚拟机会先查

看XX:

HandlePromotionFailure参数的设置值是否允许担保失败(Handle Promotion Failure);如果允

许,那会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,

如果大于,将尝试进行一次Minor GC,尽管这次Minor GC是有风险的;如果小于,或者-XX:

HandlePromotionFailure设置不允许冒险,那这时就要改为进行一次Full GC。

“冒险”是冒了什么风险:前面提到过,新生代使用复制收集算法,但为了内存利用率, 只使用其中

一个Survivor空间来作为轮换备份,因此当出现大量对象在Minor GC后仍然存活的情况,最极端的

情况就是内存回收后新生代中所有对象都存活,需要老年代进行分配担保,把Survivor无 法容纳的

对象直接送入老年代,这与生活中贷款担保类似。

老年代要进行这样的担保,前提是老年代 本身还有容纳这些对象的剩余空间,但一共有多少对象

会在这次回收中活下来在实际完成内存回收之 前是无法明确知道的,所以只能取之前每一次回收

晋升到老年代对象容量的平均大小作为经验值,与 老年代的剩余空间进行比较,决定是否进行Full

GC来让老年代腾出更多空间。

取历史平均值来比较其实仍然是一种赌概率的解决办法,也就是说假如某次Minor GC存活后的对

象突增,远远高于历史平均值的话,依然会导致担保失败。如果出现了担保失败,那就只好老老实

实 地重新发起一次Full GC,这样停顿时间就很长了。

虽然担保失败时绕的圈子是最大的,但通常情况下 都还是会将-XX:HandlePromotionFailure开关

打开,避免Full GC过于频繁。

相关文章:

03垃圾回收篇(D3_垃圾收集器的选择及相关参数)

目录 学习前言 一、收集器的选择 二、GC日志参数 三、垃圾收集相关的常用参数 四、内存分配与回收策略 1. 对象优先在Eden分配 2. 大对象直接进入老年代 3. 长期存活的对象将进入老年代 4. 动态对象年龄判定 5. 空间分配担保 学习前言 本章主要学习垃圾收集器的选择及…...

一、引论,《组合数学(第4版)》卢开澄 卢华明

零、前言 发现自己数数题做的很烂,重新学一遍组合数学吧。 参考卢开澄 卢华明 编著的《组合数学(第4版)》,只打算学前四章。 通过几个经典问题来了解组合数学所研究的内容。 一、幻方问题 据说大禹治水之前,河里冒出来一只乌龟&#xff0c…...

Vue3+TS 实现批量拖拽文件夹上传图片组件封装

1、html 代码&#xff1a; 代码中的表格引入了 vxe-table 插件 <Tag /> 是自己封装的说明组件 表格列表这块我使用了插槽来增加扩展性&#xff0c;可根据自己需求&#xff0c;在组件外部做调整 <template><div class"dragUpload"><el-dialo…...

二叉树的所有路径(力扣257)

因为题目要求路径是从上到下的&#xff0c;所以最好采用前序遍历。这样可以保证按从上到下的顺序将节点的值存入一个路径数组中。另外&#xff0c;此题还有一个难点就是如何求得所有路径。为了解决这个问题&#xff0c;我们需要用到回溯。回溯和递归不分家&#xff0c;每递归一…...

Python OrderedDict 实现 Least Recently used(LRU)缓存

OrderedDict 实现 Least Recently used&#xff08;LRU&#xff09;缓存 引言正文 引言 LRU 缓存是一种缓存替换策略&#xff0c;当缓存空间不足时&#xff0c;会移除最久未使用的数据以腾出空间存放新的数据。LRU 缓存的特点&#xff1a; 有限容量&#xff1a;缓存拥有固定的…...

LabVIEW项目中的工控机与普通电脑选择

工控机&#xff08;Industrial PC&#xff09;与普通电脑在硬件设计、性能要求、稳定性、环境适应性等方面存在显著差异。了解这些区别对于在LabVIEW项目中选择合适的硬件至关重要。下面将详细分析这两种设备的主要差异&#xff0c;并为LabVIEW项目中的选择提供指导。 ​ 硬件设…...

Ansys Speos | Speos Meshing 网格最佳实践

概述 网格划分是在各种计算应用中处理3D几何的基本步骤&#xff1a; 表面和体积&#xff1a;网格允许通过将复杂的表面和体积分解成更简单的几何元素&#xff08;如三角形、四边形、四面体或六面体&#xff09;来表示复杂的表面和体积。 模拟和渲染&#xff1a;网格是创建离散…...

elasticsearch segment数量对读写性能的影响

index.merge.policy.segments_per_tier 是一个配置选项&#xff0c;用于控制 Elasticsearch 中段&#xff08;segment&#xff09;合并策略的行为。它定义了在每一层的段合并过程中&#xff0c;允许存在的最大段数量。调整这个参数可以优化索引性能和资源使用。 假设你有一个索…...

全同态加密理论、生态现状与未来展望(中2)

《全同态加密理论、生态现状与未来展望》系列由lynndell2010gmail.com和mutourend2010gmail.com整理原创发布&#xff0c;分为上中下三个系列&#xff1a; 全同态加密理论、生态现状与未来展望&#xff08;上&#xff09;&#xff1a;专注于介绍全同态加密理论知识。全同态加密…...

鸿蒙UI(ArkUI-方舟UI框架)-开发布局

返回主章节 → 鸿蒙UI&#xff08;ArkUI-方舟UI框架&#xff09; 开发布局 1、布局概述 1&#xff09;布局结构 2&#xff09;布局元素组成 3&#xff09;如何选择布局 声明式UI提供了以下10种常见布局&#xff0c;开发者可根据实际应用场景选择合适的布局进行页面开发。 …...

RPC是什么?和HTTP区别?

RPC 是什么&#xff1f;HTTP 是什么&#xff1f; 作为一个程序员&#xff0c;假设我们需要从A电脑的进程发送一段数据到B电脑的进程&#xff0c;我们一般会在代码中使用 Socket 进行编程。 此时&#xff0c;可选性一般就是 TCP 和 UDP 二选一&#xff0c;由于 TCP 可靠、UDP 不…...

Linux C\C++编程-建立文件和内存映射

【图书推荐】《Linux C与C一线开发实践&#xff08;第2版&#xff09;》_linux c与c一线开发实践pdf-CSDN博客 《Linux C与C一线开发实践&#xff08;第2版&#xff09;&#xff08;Linux技术丛书&#xff09;》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 Linu…...

行政纠错——pycorrector学习

pycorrector是一个开源中文文本纠错工具&#xff0c;它支持对中文文本进行音似、形似和语法错误的纠正。此工具是使用Python3进行开发的&#xff0c;并整合了Kenlm、ConvSeq2Seq、BERT、MacBERT、ELECTRA、ERNIE、Transformer等多种模型来实现文本纠错功能。pycorrector官方仓库…...

Go的defer原理

Go 的 defer 原理 defer 是 Go 语言中的一个关键字&#xff0c;用于延迟执行一个函数调用。它通常用于处理资源释放、连接关闭等操作&#xff0c;确保这些操作在函数返回之前执行。 1. 什么是 defer&#xff1f; defer 关键字用于延迟执行一个函数调用&#xff0c;直到包含它…...

Windows 下本地 Docker RAGFlow 部署指南

Windows 下本地 Docker RAGFlow 部署指南 环境要求部署步骤1. 克隆代码仓库2. 配置 Docker 镜像加速(可选)3. 修改端口配置(可选)4. 启动服务5. 验证服务状态6. 访问服务7. 登录系统8. 配置模型8.1 使用 Ollama 本地模型8.2 使用在线 API 服务9. 开始使用10. 常见问题处理端…...

专题三_穷举vs暴搜vs深搜vs回溯vs剪枝_全排列

dfs解决 全排列&子集 1.全排列 link:46. 全排列 - 力扣&#xff08;LeetCode&#xff09; 全局变量回溯 code class Solution { public:vector<vector<int>> ans;vector<int> cur;vector<bool> used;vector<vector<int>> permute…...

【IEEE Fellow 主讲报告| EI检索稳定】第五届机器学习与智能系统工程国际学术会议(MLISE 2025)

重要信息 会议时间地点&#xff1a;2025年6月13-15日 中国深圳 会议官网&#xff1a;http://mlise.org EI Compendex/Scopus稳定检索 会议简介 第五届机器学习与智能系统工程国际学术会议将于6月13-15日在中国深圳隆重召开。本次会议旨在搭建一个顶尖的学术交流平台&#xf…...

华为E9000刀箱服务器监控指标解读

美信监控易内置了数千种常见设备监测器&#xff0c;能够监测超过20万项指标。这些指标涵盖了从硬件设备到软件系统&#xff0c;从网络性能到安全状态等各个方面。如下基于美信监控易——IT基础监控模块&#xff0c;对华为E9000刀箱服务器部分监控指标进行解读。 一、华为E9000…...

【LC】2544. 交替数字和

题目描述&#xff1a; 给你一个正整数 n 。n 中的每一位数字都会按下述规则分配一个符号&#xff1a; 最高有效位 上的数字分配到 正 号。剩余每位上数字的符号都与其相邻数字相反。 返回所有数字及其对应符号的和。 示例 1&#xff1a; 输入&#xff1a;n 521 输出&…...

QT QTreeWidget控件 全面详解

本系列文章全面的介绍了QT中的57种控件的使用方法以及示例,包括 Button(PushButton、toolButton、radioButton、checkBox、commandLinkButton、buttonBox)、Layouts(verticalLayout、horizontalLayout、gridLayout、formLayout)、Spacers(verticalSpacer、horizontalSpacer)、…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...