当前位置: 首页 > 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)、…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

小木的算法日记-多叉树的递归/层序遍历

&#x1f332; 从二叉树到森林&#xff1a;一文彻底搞懂多叉树遍历的艺术 &#x1f680; 引言 你好&#xff0c;未来的算法大神&#xff01; 在数据结构的世界里&#xff0c;“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的&#xff0c;它…...

STM32标准库-ADC数模转换器

文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”&#xff1a;输入模块&#xff08;GPIO、温度、V_REFINT&#xff09;1.4.2 信号 “调度站”&#xff1a;多路开关1.4.3 信号 “加工厂”&#xff1a;ADC 转换器&#xff08;规则组 注入…...