【开发篇】十三、JVM基础参数设置与垃圾回收器的选择

文章目录

  • 1、-Xmx 和 –Xms
  • 2、-XX:MaxMetaspaceSize 和 –XX:MetaspaceSize
  • 3、-Xss
  • 4、不建议改的参数
  • 5、其他参数
  • 6、选择GC回收器的调试思路
  • 7、CMS的并发模式失败现象的解决
  • 8、调优案例

GC问题解决方式:

  • 优化JVM基础参数,避免频繁Full GC
  • 减少对象的产生,以免对象产生速度过快导致频繁Full GC
  • 选择适合业务场景的垃圾回收器
  • 优化垃圾回收器的参数

1、-Xmx 和 –Xms

-Xmx设置最大堆内存(max),-Xms设置可用堆内存大(total)

在这里插入图片描述
计算理论最大可用堆空间,如服务器内存4G,操作系统自己使用的内存+元空间最大值+其它软件占用1.5G ⇒ 理论最大可用堆空间为2.5g,只是理论值。(减去元空间是因为,Java 8及以后,元空间使用的是直接内存)

在这里插入图片描述
最后设置的堆内存大小,应是按照系统最大并发估计,且小于上面的理论值。最后,将-Xms设置的和-Xmx一样大,理由:

  • 可用内存一开始就等于最大堆内存,避免堆扩容时频繁向操作系统申请内存,影响程序性能
  • 避免扩容时,因其他应用占用了操作系统内存而申请扩容失败
  • 服务启动速度更快,初始堆太小(Xms太小),Java应用启动会变慢,因为JVM会被迫频繁垃圾回收,直到堆增长到一个合理的大小

2、-XX:MaxMetaspaceSize 和 –XX:MetaspaceSize

-XX:MaxMetaspaceSize :最大元空间。默认值比较大,万一元空间内存泄漏,会影响到操作系统(因为元空间用的直接内存)

–XX:MetaspaceSize:到这个值后,触发Full GC,后续什么值再触发,JVM自行计算。

在这里插入图片描述

3、-Xss

指定每个栈的大小,不指定取默认值,默认值取决于操作系统。如Linux x86 64bit 默认是1MB。如果没有方法的递归调用,可调小栈大小

//合理值为256k – 1m之间
-Xss256k

4、不建议改的参数

以下参数,调整可能会让某一个接口得益,但同时也会影响其他接口,不建议修改。

1-Xmn:年轻代的大小

年轻代的大小,默认为整个堆的1/3。可根据系统峰值计算年轻代大小,以尽量让对象只存在年轻代,不进入老年代(这样后面Young GC一下就行),但计算这个值的影响因素太多,不建议改。且G1垃圾回收器会动态调整年轻代的大小,更不建议改。

在这里插入图片描述

2)‐XX:SurvivorRatio 伊甸园区和幸存者区的大小比例,默认值为8

在这里插入图片描述

3)‐XX:MaxTenuringThreshold 最大晋升阈值

对象晋升有两个情况:

  • (GC一次,对象年龄+1)年龄 > 此值,进入老年代
  • 动态年龄判断机制:按年龄从小到大将对象空间加起来, > survivor区域的50%,就把大于等于该年龄的对象晋升到老年代

在这里插入图片描述

5、其他参数

-XX:+DisableExplicitGC作用:禁止在代码中调用System.gc()
-XX:+HeapDumpOnOutOfMemoryError作用:OOM时,生成hprof内存快照文件
-XX:HeapDumpPath=<path>作用:指定内存快照文件的生成路径
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:文件路径作用:JDK8及之前,打印GC日志
-Xlog:gc*:file=文件路径作用:JDK9及以后,打印GC日志


JVM参数模板总结:

-Xms1g
-Xmx1g
-Xss256k
-XX:MaxMetaspaceSize=512m 
-XX:+DisableExplicitGC
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/opt/logs/my-service.hprof
# <=JDK8
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps# >=JDK9
-Xloggc:文件路径

6、选择GC回收器的调试思路

用以下代码模拟系统的业务代码进行压测:

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.SneakyThrows;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;@RestController
@RequestMapping("/fullgc")
public class DemoController {private Cache cache = Caffeine.newBuilder().weakKeys().softValues().build();private List<Object> objs = new ArrayList<>();private static final int _1MB = 1024 * 1024;//FULLGC测试结果://ps + po 50并发 260ms  100并发 474ms  200并发 930ms//cms -XX:+UseParNewGC -XX:+UseConcMarkSweepGC 50并发 157ms  200并发 833ms//g1 JDK11 并发200 248@GetMapping("/1")public void test() throws InterruptedException {cache.put(RandomStringUtils.randomAlphabetic(8),new byte[10 * _1MB]);}}

创建一个具有弱引用键(value不存在了,可被GC回收)和软引用值的缓存对象(内存不足时,可GC回收),接口往里面放10M的数据,如此,不会OOM,且会较多触发FULL GC。用Jmeter并发/1接口的同时,再调用一次接口/2,用这个接口模拟有突发大对象产生时,对系统响应时间的影响:

@GetMapping("/2")
public void test() throws InterruptedException {ArrayList<Object> objects = new ArrayList<>();for (int i = 0; i < 1024; i++) {objects.add(new byte[3 * _1MB]);}
}

步骤:

  • Jmeter脚本压测,添加RT响应时间组件
  • 选择不同的垃圾回收器组合,测试50、100、200并发下,FULL GC对RT的时间的影响

统一JVM参数设置:

-Xms8g -Xmx8g -Xss256k -XX:MaxMetaspaceSize=512m  -XX:+DisableExplicitGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:/test.hprof  -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps

测试的垃圾回收器组合:

  • ps + po
  • cms
  • JDK11的默认回收器g1

测试场景:

  • 高并发(/1接口)
  • 大对象产生(/2接口)

观察RT的结果:查看最大值,即接口的最大响应时间。峰值的出现,即FULL GC对接口响应时间的影响
在这里插入图片描述

7、CMS的并发模式失败现象的解决

CMS的垃圾清理线程和用户线程并行

在这里插入图片描述

如果并行清理的过程中,老年代的空间,不足以容纳新晋升到老年代的对象,就发生并发模式失败:

在这里插入图片描述

出现并发模式失败时,会导致JVM使用Serial Old单线程进行FULLGC回收老年代,这样会产生较长时间的停顿,从而影响接口响应时间。解决思路:

  • 减少对象的产生以及晋升
  • 增加堆内存大小
  • -XX:CMSInitiatingOccupancyFraction=

关于垃圾回收器的参数CMSInitiatingOccupancyFraction,当老年代大小达到其值,会自动进行CMS老年代垃圾回收。JDK8中,该值为-1,计算公式:

((100 - MinHeapFreeRatio) + (double)(CMSTriggerRatio * MinHeapFreeRatio) / 100.0)

最后,这个参数想生效,必须先开启:

-XX:+UseCMSInitiatingOccupancyOnly

调小这个值,比如从默认的90%调到60%,早些进行老年代的回收,就不会出现并发模式失败,也就不会有后面的Serial Old单线程回收老年代。

8、调优案例

案例背景:

  • 系统的接口在平时响应较快,但高峰期会出现调用时间较长的现象,现需要优化性能

分析的方向:

  • GC问题:查看是否出现连续的Full GC或者单次GC时间过长
  • 内存问题

步骤:

  • 生成GC报告,GcEasy分析
  • GC有问题,就调整参数或者换垃圾回收器
  • 内存有问题就jmap或Arthas将堆内存快照保存
  • MAT或者heaphero在线分析内存
  • 修复

关于heaphero:https://heaphero.io/

调优案例:https://www.bilibili.com/video/BV1r94y1b7eS?p=68&vd_source=d86e858b4dfd8944a691759448d35279

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

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

相关文章

0基础如何入门编程?

0基础如何进入IT行业 &#xff1f; 前言 简介&#xff1a;对于没有任何相关背景知识的人来说&#xff0c;如何才能成功进入IT行业&#xff1f;是否有一些特定的方法或技巧可以帮助他们实现这一目标&#xff1f; 主要方法有如下几点建议提供给宝子们 目录 免费视频网课学习…

读书笔记之《如何精心设计提示词来精通ChatGPT》

《如何精心设计提示词来精通ChatGPT》这本书英文标题为&#xff1a;《The Art of Prompt Engineering with chatGPT》&#xff0c;于2023年出版。作者是Nathan Hunter 。 Nathan Hunter简介&#xff1a;ChatGPT培训的创始人。作为一名资深培训师和教学设计师&#xff0c;我在过…

Spring Cloud 集成 Redis 发布订阅

目录 前言步骤引入相关maven依赖添加相关配置 使用方法发布订阅发布一个消息 注意总结 前言 在当今的软件开发领域&#xff0c;分布式系统已经成为一种主流的架构模式&#xff0c;尤其是在处理大规模、高并发、高可用的业务场景时。然而&#xff0c;随着系统复杂性的增加&…

elementor和divi的对比,哪个更适合你,他们国产化替代方案

Elementor和Divi都是流行的WordPress页面构建器&#xff0c;它们各自具有一些独特的优点和缺点。现在有越来越多的应用服务商开发了自助建站工具&#xff0c;通过自助建站工具&#xff0c;我们可以轻松的创建一个看起来很专业的网站。但在眼花缭乱的软件产品面前&#xff0c;我…

SpringMVC(三)【REST 风格】

1、REST 风格 1.1、REST 简介 REST&#xff08;Representational State Transfer&#xff09;&#xff0c;表现形式状态转换 在开发中&#xff0c;它其实指的就是访问网络资源的格式 1.1.1、传统风格资源描述形式 http://localhost/user/getById?id1http://localhost/user…

数据结构——栈(C++实现)

数据结构——栈 什么是栈栈的实现顺序栈的实现链栈的实现 今天我们来看一个新的数据结构——栈。 什么是栈 栈是一种基础且重要的数据结构&#xff0c;它在计算机科学和编程中扮演着核心角色。栈的名称源于现实生活中的概念&#xff0c;如一叠书或一摞盘子&#xff0c;新添加…

【C++初阶】C++简单入门(长期维护)

本篇博客是对C的一些简单知识分享&#xff0c;有需要借鉴即可。 C简单入门目录 一、C前言1.C的概念&#xff1a;2.C发展历程3.C如何学&#xff1f; 二、C入门1.C关键字(C98标准)2.命名空间3.C输入&输出①概念说明②使用说明③特征说明④细节拓展⑤cout与cin的意义 4.缺省参…

处理json文件,并将数据汇总至Excel表格

从scores.jason文件中读取学生信息,输出学生的学号&#xff0c;姓名&#xff0c;各科成绩&#xff0c;平均分, 各科标准差 scores.jason {"学院": "计算机学院","班级": "2022级1班","成绩": [{"学号": 1001,&q…

【vue】绑定事件 v-on

v-on 简写&#xff1a; clickkeyupkeydownkeyup.wkeyup.ctrl.a <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><…

BK9534 博通BEKEN 无线麦克风芯片 提供配置工具软件

BK9534 芯片是在 BK9532 芯片基础上增加了一个内置MCU 来实现单芯片简单工作模式&#xff0c;内置己经固化了如开关机&#xff0c;对码&#xff0c;低电侦测&#xff0c;自动频率跟随等基本功能。另外还可以借助工具修改如频率&#xff0c;ID等相关配置信息. 1. 升级了接收芯片…

SpringBoot修改菜品模块开发

需求分析与设计 一&#xff1a;产品原型 在菜品管理列表页面点击修改按钮&#xff0c;跳转到修改菜品页面&#xff0c;在修改页面回显菜品相关信息并进行修改&#xff0c;最后点击保存按钮完成修改操作。 修改菜品原型&#xff1a; 二&#xff1a;接口设计 通过对上述原型图…

Midjourney常见玩法及prompt关键词技巧

今天系统给大家讲讲Midjourney的常见玩法和prompt关键词的一些注意事项&#xff0c;带大家入门&#xff5e;&#xff08;多图预警&#xff0c;建议收藏&#xff5e;&#xff09; 一、入门及常见玩法 1、注册并添加服务器&#xff08;会的童鞋可跳过&#xff5e;&#xff09; …

SpringBoot与MyBatisPlus的依赖版本冲突问题

记录使用SpringBoot和MyBatisPlus时遇到的版本冲突问题解决。 java版本&#xff1a;jdk17 废话&#xff1a;&#xff09;目前在IDEA中使用Spring官方的脚手架最低jdk版本竟然是jdk17了。 当使用SpringBoot3.0版本(3.2.4)&#xff0c;配合使用MP3.5.2版本时报错&#xff1a; Er…

H5代码video标签引入视频在浏览器的兼容性问题解决办法

H5标签video引入视频&#xff0c;在谷歌浏览器正常但是在火狐浏览器和版本较低的浏览器或者IE浏览器却无法观看视频&#xff0c;只能看到音频&#xff0c;是什么原因&#xff1f; 代码如下 <video class"video" muted loop"loop" style"display…

前端三剑客 —— JavaScript (第九节)

目录 内容回顾&#xff1a; 1.事件解除 2. Ajax jQuery选择器 回顾CSS选择器 CSS选择 1.基本选择器 2.包含选择器 3.伪类选择器 4.伪元素选择器 5.属性选择器 jQuery 库 jQuery 动画 系统动画 自定义动画 常见API操作 内容回顾&#xff1a; 1.事件解除 如果是使…

《由浅入深学习SAP财务》:第2章 总账模块 - 2.6 定期处理 - 2.6.3 月末操作:外币评估

2.6.3 月末操作&#xff1a;外币评估 企业的外币业务在记账时一般使用期初的汇率或者即时汇率&#xff0c;但在月末&#xff0c;需要按照月末汇率对外币的余额或者未清项进行重估&#xff08;revaluation&#xff09;。 企业在资产负债表日&#xff0c;应当按照下列规…

微信小程序全局配置

全局配置文件及常用的配置项 小程序根目录下的 app.json 文件是小程序的全局配置文件。常用的配置项如下&#xff1a; ① pages 记录当前小程序所有页面的存放路径 ② window 全局设置小程序窗口的外观 ③ tabBar 设置小程序底部的 tabBar 效果 ④ style 是否启用新版的组件样…

SpringBoot菜品分页查询模块开发(多表连接查询)

需要注意的地方 为什么创建VO类怎么进行多表连接查询分页查询的统一返回结果类PageResult分页查询Mapper的返回结果是Page<目标实体类> 需求分析与设计 一&#xff1a;产品原型 系统中的菜品数据很多的时候&#xff0c;如果在一个页面中全部展示出来会显得比较乱&…

华火电燃灶荣获国家级科技型中小企业

华火电燃灶作为一家国家级科技型中小企业&#xff0c;凭借其创新的技术和卓越的产品性能&#xff0c;在新能源厨电领域取得了显著的成就。华火&#xff0c;潜心钻研等离子电生明火技术近十年&#xff1b;华火电燃灶&#xff0c;电生明火&#xff0c;以“电”作为唯一能源&#…

创建影子用户

文章目录 1.认识影子用户2.创建隐藏账户并加入管理员组3.修改注册表3.删除用户4.添加管理员权限 1.认识影子用户 影子用户通常指的是那些在系统用户列表中不可见&#xff0c;但在某些情况下可以进行操作的用户。在内网渗透过程中&#xff0c;当我们拿到shell时&#xff0c;肯定…