JAVA虚拟机实战篇之GC调优[2](解决GC问题的手段)

文章目录

  • 版权声明
  • 解决GC问题的手段
  • 优化基础JVM参数
    • -Xmx 和 –Xms
    • -XX:MaxMetaspaceSize 和 –XX:MetaspaceSize
    • -Xss虚拟机栈大小
    • ‐XX:SurvivorRatio和‐XX:MaxTenuringThreshold
    • -XX:+DisableExplicitGC
  • 案例:垃圾回收器的选择
    • 复习:垃圾回收器的组合关系
    • 背景
    • 思路
  • 案例:优化垃圾回收器的参数
    • 解决方案

版权声明

  • 本博客的内容基于我个人学习黑马程序员课程的学习笔记整理而成。我特此声明,所有版权属于黑马程序员或相关权利人所有。本博客的目的仅为个人学习和交流之用,并非商业用途。
  • 我在整理学习笔记的过程中尽力确保准确性,但无法保证内容的完整性和时效性。本博客的内容可能会随着时间的推移而过时或需要更新。
  • 若您是黑马程序员或相关权利人,如有任何侵犯版权的地方,请您及时联系我,我将立即予以删除或进行必要的修改。
  • 对于其他读者,请在阅读本博客内容时保持遵守相关法律法规和道德准则,谨慎参考,并自行承担因此产生的风险和责任。
  • 本博客中的部分观点和意见仅代表我个人,不代表黑马程序员的立场。
    在这里插入图片描述

解决GC问题的手段

在这里插入图片描述

  • 解决GC问题的手段中,比较推荐前三种手段
  1. 优化基础JVM参数
    • 基础JVM参数的设置不当,会导致频繁产生FULL GC
  2. 减少对象产生
    • 大多数场景下的FULL GC是由于对象产生速度过快导致,减少对象的产生可以有效地缓解FULL GC的发生
  3. 更换垃圾回收器
    • 选择合适当前业务场景的垃圾回收器,可以减少延迟、提高吞吐量
  4. 优化垃圾回收器参数
    • 优化垃回收器的参数,能在一定程度上提升GC效率

优化基础JVM参数

-Xmx 和 –Xms

  • -Xmx:设置的是最大堆内存,但是由于程序是运行在服务器或者容器上,计算可用内存时,要将元空间、操作系统、其它软件占用的内存排除掉。
  • 案例: 服务器内存4G,操作系统+元空间最大值+其它软件占用1.5G,-Xmx可以设置为2g。
  • 最合理的设置方式应该是根据最大并发量估算服务器的配置,然后再根据服务器配置计算最大堆内存的值。
    在这里插入图片描述
  • -Xms用来设置初始堆大小,建议将-Xms设置的和-Xmx一样大,有以下几点优势
  • 运行性能更好,堆的扩容是需要向操作系统申请内存,会导致程序性能短期下降。
  • 可用性问题,如果在扩容时其他程序正在使用大量内存,很容易因为操作系统内存不足分配失败。
  • 启动速度更快,如果初始堆太小,Java 应用程序启动会变得很慢,因为 JVM 被迫频繁执行垃圾收集,直到堆增长到更合理的大小。为获得最佳启动性能,请将初始堆大小设置为与最大堆大小相同。

-XX:MaxMetaspaceSize 和 –XX:MetaspaceSize

  • -XX:MaxMetaspaceSize=值 参数指最大元空间大小,默认值比较大,如果出现元空间内存泄漏会让操作系统可用内存不可控,建议根据测试情况设置最大值,一般设置为256m。
  • -XX:MetaspaceSize=值 参数指到达该值之后会触发FULLGC,后续触发时机JVM会自行计算。如果设置为MaxMetaspaceSize一样大,就不会FULLGC,但是对象也无法回收。
    在这里插入图片描述

-Xss虚拟机栈大小

  • 如果不指定栈的大小,JVM 将创建一个具有默认大小的栈。大小取决于操作系统和计算机的体系结构。比如Linux x86 64位 1 M B 1MB 1MB,如果不需要用到这么大的栈内存,可以将此值调小节省内存空间,合理值为 256 k – 1 m 256k – 1m 256k–1m之间。
  • 使用: − X s s 256 k -Xss256k Xss256k

‐XX:SurvivorRatio和‐XX:MaxTenuringThreshold

  • 不建议手动设置的参数
  • 由于JVM底层设计极为复杂,一个参数的调整也许让某个接口得益,但同样有可能影响其他更多接口。
  • -Xmn年轻代的大小,默认值为整个堆的 1 / 3 1/3 1/3,可以根据峰值流量计算最大的年轻代大小,尽量让对象只存放在年轻代,不进入老年代。但是实际场景中,接口的响应时间、创建对象的大小、程序内部还会有一些定时任务等不确定因素都会导致这个值的大小并不能仅凭计算得出,如果设置该值要进行大量的测试。G1垃圾回收器尽量不要设置该值,G1会动态调整年轻代的大小。
    在这里插入图片描述

  • ‐XX:SurvivorRatio伊甸园区和幸存者区的大小比例,默认值为 8 8 8
  • ‐XX:MaxTenuringThreshold最大晋升阈值,年龄大于此值之后,会进入老年代。另外JVM有动态年龄判断机制:将年龄从小到大的对象占据的空间加起来,如果大于 s u r v i v o r survivor survivor区域的 50 50% 50,然后把等于或大于该年龄的对象,放入到老年代。

在这里插入图片描述

-XX:+DisableExplicitGC

  • -XX:+DisableExplicitGC禁止在代码中使用 S y s t e m . g c ( ) System.gc() System.gc() S y s t e m . g c ( ) System.gc() System.gc()可能会引起 F U L L G C FULLGC FULLGC,在代码中尽量不要使用。使用 D i s a b l e E x p l i c i t G C DisableExplicitGC DisableExplicitGC参数可以禁止使用 S y s t e m . g c ( ) System.gc() System.gc()方法调用。
  • -XX:+HeapDumpOnOutOfMemoryError:发生 O u t O f M e m o r y E r r o r OutOfMemoryError OutOfMemoryError错误时,自动生成 h p r o f hprof hprof内存快照文件。
  • -XX:HeapDumpPath=<path>:指定 h p r o f hprof hprof文件的输出路径。
  • 打印GC日志
    • JDK8及之前 :-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:文件路径
    • JDK9及之后 :-Xlog:gc*:file=文件路径

案例:垃圾回收器的选择

复习:垃圾回收器的组合关系

在这里插入图片描述

背景

  • 小李负责的程序在高峰期遇到了性能瓶颈,团队从业务代码入手优化了多次也取得了不错的效果,这次他希望能采用更合理的垃圾回收器优化性能。

思路

  1. 编写Jmeter脚本对程序进行压测,同时添加RT响应时间、每秒钟的事务数等指标进行监控。
  2. 选择不同的垃圾回收器进行测试,并发量分别设置50、100、200,观察数据的变化情况
  3. JDK8 下 ParNew + CMS 组合 : -XX:+UseParNewGC -XX:+UseConcMarkSweepGC
    • 默认组合 : PS + PO
    • JDK8使用g1 : -XX:+UseG1GC
    • JDK11 默认 g1

案例:优化垃圾回收器的参数

  • 优化的案例:CMS的并发模式失败(concurrent mode failure)现象。由于CMS的垃圾清理线程和用户线程是并行进行的,如果在并发清理的过程中老年代的空间不足以容纳放入老年代的对象,会产生并发模式失败。
    在这里插入图片描述
    在这里插入图片描述
  • 并发模式失败会导致Java虚拟机使用Serial Old单线程进行FULLGC回收老年代,出现长时间的停顿。
    在这里插入图片描述

解决方案

  1. 减少对象的产生以及对象的晋升
  2. 增加堆内存大小
  3. 优化垃圾回收器的参数,如-XX:CMSInitiatingOccupancyFraction=值,当老年代大小到达该阈值时,会自动进行CMS垃圾回收,通过控制这个参数提前进行老年代的垃圾回收,减少其大小。JDK8中默认参数值为-1,根据其他几个参数计算出阈值:((100 - MinHeapFreeRatio) + (double)(CMSTriggerRatio * MinHeapFreeRatio) / 100.0)该参数设置完是不会生效的,必须开启-XX:+UseCMSInitiatingOccupancyOnly参数。
  • 调整之后的效果
    在这里插入图片描述

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

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

相关文章

vue 元素拖动,复制,已复制元素可移动,快捷方便,已解决

注意&#xff1a;使用当前组件时&#xff0c;请先了解组件代码逻辑 下方组件根据自己的需求来更改响应的元素id&#xff0c;调整代码实现逻辑&#xff0c;这里不过多解释 import Vue from "vue";/*** 拖拽*/ Vue.directive("Drag", (el) > {const move…

MySQL表内容的增删查改

在前面几章的内容中我们学习了数据库的增删查改&#xff0c;表的增删查改&#xff0c;这一篇我们来学习一下对表中的内容做增删查改。 CRUD : Create(创建), Retrieve(读取)&#xff0c;Update(更新)&#xff0c;Delete&#xff08;删除&#xff09; 1.创建Create 我们先创建…

深入解析MD5哈希算法:原理、应用与安全性

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 本文将深入探讨MD5哈希算法的工作原理、应用场景以及安全性问题。我们将了解MD5如何生成固定长度的哈希值&#xff0c;以及它在数…

BUG未解之谜01-指针引用之谜

在leetcode里面刷题出现的问题&#xff0c;当我在sortedArrayToBST里面给root赋予初始值NULL之后&#xff0c;问题得到解决&#xff01; 理论上root是未初始化的变量&#xff0c;然后我进入insert函数之后&#xff0c;root引用的内容也是未知值&#xff0c;因此无法给原来的二叉…

could not resolve com.android.tools.build:gradle:4.1.1.

一、报错信息 could not resolve com.android.tools.build:gradle:4.1.1.其实是因为你的网络不能从AS工程提供的mavenCentral()、google()和jcenter()等仓库下载相应的依赖。 二、解决方法 在build.gradle(Project)中&#xff0c;在原先的maven仓库前加上阿里云镜像源。这里…

如何遍历整个DOM树

原文链接&#xff1a;[如何遍历整个DOM树(外网原文链接)](https://chrisdeo.github.io/2019/07/20/%E5%A6%82%E4%BD%95%E9%81%8D%E5%8E%86%E6%95%B4%E4%B8%AADOM%E6%A0%91/) 作为前端开发工程师&#xff0c;我们大部分工作内容其实还是围绕着DOM在进行Javascript的编写&#xf…

SQL把统计结果作为条件进行查询

今天在社区看到一个问题如何返回 统计数值&#xff0c;比较简单&#xff0c;分享一下写法&#xff1a; --测试数据 if not object_id(NTempdb..#T) is nulldrop table #T Go Create table #T([name] nvarchar(21),[year] nvarchar(21),[time] nvarchar(22)) Insert #T select …

手写SpringBoot(二)之动态切换Servlet容器

系列文章目录 手写SpringBoot&#xff08;一&#xff09;之简易版SpringBoot 手写SpringBoot&#xff08;二&#xff09;之动态切换Servlet容器 手写SpringBoot&#xff08;二&#xff09;之动态切换Servlet容器 文章目录 系列文章目录手写SpringBoot&#xff08;二&#xff…

KubeSphere简单介绍及安装使用

KubeSphere 概述 官网地址&#xff1a;https://kubesphere.io/zh/ 什么是 kubesphere KubeSphere 是一个开源的多云容器管理平台&#xff0c;旨在简化企业级 k8s 集群的部署、管理和运维。它提供了一个可视化的管理界面&#xff0c;帮助用户更轻松地管理和监控 k8s 集群&…

访问者模式(数据与行为解耦)

目录 前言 UML plantuml 类图 实战代码 SimpleFileVisitor FileVisitor 接口 删除指定文件夹 模板 IVisitor IVisitable Client 前言 一个类由成员变量和方法组成&#xff0c;成员变量即是类的数据结构&#xff0c;方法则是类的行为。 如果一个类的数据结构稳定&am…

超声波清洗机家用的哪家好?眼镜清洗器推荐!一分钟选购洗眼镜机

相信大家都知道&#xff0c;眼镜脏的话可以使用超声波清洗机清洁&#xff01;因为超声波清洗机能够通过振频的原理&#xff0c;对眼镜的污垢进行清洗。有的朋友会问&#xff0c;我手洗不可以吗&#xff1f;手洗当然可以&#xff0c;但是手洗对于镜片的清洗有作用&#xff0c;但…

【C语言】 gets()puts()fgets()fputs()字符串输入输出函数的用法

文章目录 C语言中的字符串输入输出函数&#xff1a;gets、puts、fgets与fputsgets函数puts函数fgets函数fputs函数 C语言中的字符串输入输出函数知识点总结结语 C语言中的字符串输入输出函数&#xff1a;gets、puts、fgets与fputs 在C语言中&#xff0c;处理字符串的输入和输出…

Java关键字之 assert

语法 assert关键字语法有两种用法&#xff1a; 1、assert <boolean表达式> 如果<boolean表达式>为true&#xff0c;则程序继续执行。 如果为false&#xff0c;则程序抛出AssertionError&#xff0c;并终止执行。 2、assert <boolean表达式> : <错误信…

翔云身份证实名认证接口-PHP调用方法

网络平台集成实名认证接口&#xff0c;是顺应当下网络实名制规定&#xff0c;有效规避法律风险。互联网平台若没有实名认证功能&#xff0c;那么便无法保证网民用户身份的真实性&#xff0c;很有可能被虚假用户攻击&#xff0c;特别是在当网络平台产生垃圾信息乃至是违法信息时…

必示科技携手云杉网络发布“智能可观测性联合解决方案”

近日&#xff0c;必示科技与云杉网络携手发布“智能可观测性联合解决方案”&#xff0c;整体方案融合云杉网络DeepFlow产品在可观测性领域、必示科技AIOps产品在运维数据分析领域的深厚技术积淀&#xff0c;完整实现IT系统高质量、高性能、全栈的可观测数据采集、智能监控和智能…

Go —— defer

defer defer 语句用于延迟函数的调用&#xff0c;常用于关闭文件描述符、释放锁等资源释放场景。但 defer 关键字只能作用于函数或函数调用。 defer func(){ // 函数fmt.Print("Hello&#xff0c;World!") }()defer fmt.Print("Hello&#xff0c;World!&…

第十三届国际纯数学与应用数学会议(ICPAM 2024)即将召开!

第十三届国际纯数学与应用数学会议将于2024年7月17日至20日在克罗地亚萨格勒布召开。ICPAM是一项连续成功举办十二年的年度会议&#xff0c;其汇集了纯数学和应用数学领域的教授、研究人员、学者和学生&#xff0c;为跨行业交流&#xff0c;经验分享&#xff0c;学术界合作以及…

ArcGIS Pro横向水平图例

终于知道ArcGIS Pro怎么调横向图例了&#xff01; 简单的像0一样 旋转&#xff0c;左转右转随便转 然后调整图例项间距就可以了&#xff0c;参数太多就随便试&#xff0c;总有一款适合你&#xff01; 要调整长度&#xff0c;就调整图例块的大小。完美&#xff01; 好不容易…

【C++】手撕哈希表的闭散列和开散列

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;手撕哈希表的闭散列和开散列 > 毒鸡汤&#xff1a;谁不是一边受伤&#xff0c;一边学会坚强。 > 专栏选自&#xff1a;C嘎嘎进阶 > 望小伙伴们…

对AOP的理解

目录 一、为何需要AOP&#xff1f;1、从实际需求出发2、现有的技术能解决吗&#xff1f;3、AOP可以解决 二、如何实现AOP&#xff1f;1、基本使用2、更推荐的做法2.1 “基本使用”存在的隐患2.2 最佳实践2.2.1 参考Transactional&#xff08;通过AOP实现事务管理&#xff09;2.…