java里内存、GC、性能调优的常用方法

news2026/3/17 14:28:56
内存调优内存泄漏memory leak在Java中如果不再使用一个对象但是该对象依然在GC ROOT的引用链上这个对象就不会被垃圾回收器回收这种情况就称之为内存泄漏。常见的GC ROOT线程栈里的局部变量publicvoidfoo(){PersonpnewPerson();// p 在栈帧局部变量表 → 整棵 Person 对象都是 GC Root 可达bar();}静态字段类变量publicclassCacheHolder{publicstaticMapLong,OrderorderCachenewConcurrentHashMap();//静态字段引用的 ConcurrentHashMap 实例是 GC Root}正在加锁的对象synchronized(myLock){// myLock 对象被当前线程持有doSomething();}堆内存状况的对比使用VisualVM查看- 正常情况处理业务时会出现上下起伏业务对象频繁创建内存会升高触发MinorGC之后内存会降下来。手动执行FULL GC之后内存大小会骤降而且每次降完之后的大小是接近的。长时间观察内存曲线应该是在一个范围内。- 出现内存泄漏- 处于持续增长的情况即使Minor GC也不能把大部分对象回收- 手动FULL GC之后的内存量每一次都在增长- 长时间观察内存曲线持续增长生成内存快照的Java虚拟机参数在发生溢出的时候-XX:HeapDumpOnOutOfMemoryError发生OutOfMemoryError错误时自动生成hprof内存快照文件。-XX:HeapDumpPath指定hprof文件的输出路径。–Xmx堆的最大值和-Xms (堆的初始total)-Xmx256m -Xms256m -XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPathD:\jvm\dump\test1.hprof手动生成快照这个过程中会影响用户的使用通过JDK自带的jmap命令导出格式为jmap -dump:live,formatb,file文件路径和文件名 进程ID通过arthas的heapdump命令导出格式为heapdump --live 文件路径和文件名导出后的hprof通过mat打开后可以通过TaskThread定位到当前正在执行的线程里正在执行的方法从支配树里找到此时线程正在执行的方法先找tomcat里的TaskThread然后找HandlerExecutionChain或者HandlerMethod鼠标右键后选择list objects然后选with outgoing references选项英文直译实际含义用途with outgoing references“出引用”这条对象内部都引用了谁想看“它把内存压给了哪些对象”往下追内存泄漏源头。with incoming references“入引用”都有哪些对象引用了它想看“是谁在抓着它不放”往上追为什么它没被 GC。通过 outgoing references就可以找到他调用的方法。通过VisualVM监听远程java进程启动命令java \-Dcom.sun.management.jmxremote \-Dcom.sun.management.jmxremote.port9010\-Dcom.sun.management.jmxremote.authenticatefalse\-Dcom.sun.management.jmxremote.sslfalse\-Djava.rmi.server.hostname192.168.42.168\//你启动jar包服务器的ip-jarCoreApplication.jar写ip鼠标右键完成远程监听在线定位内存问题1、使用jmap-histo:live 进程ID 文件名 命令将内存中存活对象以直方图的形式保存到文件中这个过程会影响用户的时间但是时间比较短暂。2、分析内存占用最多的对象一般这些对象就是造成内存泄漏的原因。3、使用arthas的stack命令追踪对象创建的方法被调用的调用路径找到对象创建的根源。也可以使用btrace工具编写脚本追踪方法执行的过程。jmap-histo:live 进程ID 文件名打开导出的文件发现UserEntity的数量太多了不太正常通过arthas里的stack方法跟踪这个对象发送请求后这里就找到了方法确认实体出现方式stack com.xxx.YourEntity -n 1栈顶是你自己包 → 业务代码 new 的 → 任务完成栈顶是 FastJSON / MyBatis / Jackson → 框架反序列化 → 继续 ②找“第一次用到实体”的框架入口常见入口就 3 个直接按场景选一条Redis 反序列化stack com.xxx.framework.redis.RedisCache getCacheObject -n 1追这个方法是因为getCacheObject 肯定是我写的代码里调用的而不是工具类调用的跟踪这个能找到实际的方法MyBatis 查询stack com.xxx.mapper.YourEntityMapper select* -n 1JSON 接口stack com.alibaba.fastjson2.JSON parseObject -n 1把打印出来的第一个自己包名的方法如 com.xxx.service.impl.YourServiceImpl.findUser复制下来。直捣黄龙——trace 真正的业务方法trace com.xxx.service.impl.YourServiceImpl findUser -n 5 --skipJDKMethod false控制台就会给出完整链路Controller → Service → 框架入口 → 反序列化 → 实体.()最顶层那个 Controller 方法就是你要找的“实体使用者”。或者使用btrace方法1、下载btrace工具 官方地址https://github.com/btraceio/btrace/releases/latest2、编写btrace脚本通常是一个java文件。优点3、将btrace工具和脚本上传到服务器在服务器上运行 btrace 进程ID 脚本文件名 。4、观察执行结果首先创建一个maven项目引入依赖dependenciesdependencygroupIdorg.openjdk.btrace/groupIdartifactIdbtrace-agent/artifactIdversion${btrace.version}/versionscopesystem/scopesystemPathF:\JVMTOOLS\btrace-v2.2.4-bin.tar\btrace-v2.2.4-bin\libs\btrace-agent.jar/systemPath/dependencydependencygroupIdorg.openjdk.btrace/groupIdartifactIdbtrace-boot/artifactIdversion${btrace.version}/versionscopesystem/scopesystemPathF:\JVMTOOLS\btrace-v2.2.4-bin.tar\btrace-v2.2.4-bin\libs\btrace-boot.jar/systemPath/dependencydependencygroupIdorg.openjdk.btrace/groupIdartifactIdbtrace-client/artifactIdversion${btrace.version}/versionscopesystem/scopesystemPathF:\JVMTOOLS\btrace-v2.2.4-bin.tar\btrace-v2.2.4-bin\libs\btrace-client.jar/systemPath/dependency/dependencies编写代码BTracepublicclassTracingUserEntity{OnMethod(clazzcom.itheima.jvmoptimize.entity.UserEntity,method/.*/)publicstaticvoidtraceExecute(){jstack();}}代码拖到服务器记得btrace也得在服务器进行监听GC调优看gc信息最简单的办法jstat -gc 进程ID每次统计的间隔毫秒统计次数列名全称含义单位KBS0CSurvivor 0 Capacity年轻代第 0 个 Survivor 区总大小S1CSurvivor 1 Capacity年轻代第 1 个 Survivor 区总大小S0USurvivor 0 UsedS0 已使用大小S1USurvivor 1 UsedS1 已使用大小ECEden CapacityEden 区总大小EUEden UsedEden 已使用大小OCOld Capacity老年代总大小OUOld Used老年代已使用大小MCMetaspace CapacityMetaspace 已提交大小JDK 8MUMetaspace UsedMetaspace 已使用大小CCSCCompressed Class Space Capacity压缩类空间总大小CCSUCompressed Class Space Used压缩类空间已使用大小YGCYoung GC 次数自启动以来 Young GC 总次数YGCTYoung GC TimeYoung GC 累计耗时秒FGCFull GC 次数Full GC 总次数FGCTFull GC TimeFull GC 累计耗时秒CGCConcurrent GC 次数G1/ZGC 等并发 GC 周期次数CGCTConcurrent GC Time并发 GC 累计耗时秒GCTTotal GC Time所有 GC 累计耗时秒 YGCTFGCTCGCT例子年轻代EU≈EC 且 YGC 猛涨 → 对象朝生夕灭正常EU 一直小于 EC 但 YGC 不涨 → 流量低没事EU 长期接近 EC 且 YGC 涨得飞快 → ** Eden 太小或对象太大**考虑调大 -Xmn 或检查一次性分配大数组的代码。老年代OU 匀速上涨 FGC 上涨也清不掉 → 内存泄漏/缓存堆积OU 上涨后 FGC 一次掉回 → 正常晋升只要 FGCT 不飙高就接受FGC 次数多但 OU 几乎没降 → 老年代不足或泄露需 dump 堆。MetaspaceMU 逼近 MC 且 MC 持续上涨 → 类泄漏反射、Groovy、Jackson 动态类调大 -XX:MaxMetaspaceSize 只是缓兵之计得找代码。耗时YGCT/FGCT 任意一项单次平均超过 200 ms用总耗时÷次数→ 用户线程被暂停需要换 GC 器或调大堆。使用visualVM安装插件看-verbose:gc加在虚拟机参数可以在运行中打印gc日志直接生成专门的gc日志JDK 8及以下-XX:PrintGCDetails -Xloggc:文件名JDK 9-Xlog:gc*:file文件名将刚刚生成的日志文件使用gcviewer看或者使用 GCeasy看https://gceasy.io/优化基础JVM参数-Xmx 和 –Xms-Xms用来设置初始堆大小建议将-Xms设置的和-Xmx一样大-XX:MaxMetaspaceSize值 参数指的是最大元空间大小默认值比较大如果出现元空间内存泄漏会让操作系统可用内存不可控建议根据测试情况设置最大值一般设置为256m。-XX:MetaspaceSize值 参数指的是到达这个值之后会触发FULLGC-Xss虚拟机栈大小如果我们不指定栈的大小JVM 将创建一个具有默认大小的栈。大小取决于操作系统和计算机的体系结构。比如Linux x86 64位 1MB如果不需要用到这么大的栈内存完全可以将此值调小节省内存空间合理值为256k – 1m之间。使用-Xss256k-XX:DisableExplicitGC禁止在代码中使用System.gc() System.gc()可能会引起FULLGC在代码中尽量不要使用。使用DisableExplicitGC参数可以禁止使用System.gc()方法调用。-XX:HeapDumpOnOutOfMemoryError发生OutOfMemoryError错误时自动生成hprof内存快照文件。-XX:HeapDumpPath指定hprof文件的输出路径。打印GC日志JDK8及之前 -XX:PrintGCDetails-XX:PrintGCDateStamps-Xloggc:文件路径JDK9及之后 -Xlog:gc*:file文件路径常见模板-Xms1g# 堆初始大小1GB启动即申请避免运行时动态扩容-Xmx1g# 堆最大1GB与-Xms相同可消除堆伸缩带来的GC抖动-Xss256k# 单个线程栈大小256KB栈越深可创线程越多默认1M时可降到256k-XX:MaxMetaspaceSize512m # 元空间上限512MB防止类加载泄漏把本机内存打爆-XX:DisableExplicitGC# 屏蔽System.gc()避免代码/库主动触发FullGC造成莫名停顿-XX:HeapDumpOnOutOfMemoryError# 首次OOM时自动 dump 堆快照留作事后分析-XX:HeapDumpPath/opt/logs/my-service.hprof # 指定 dump 文件路径默认当前目录可能权限不足-Xlog:gc*:file/opt/logs/gc.log # 把GC详细日志写到文件方便GCViewer/gceasy 分析如果要查出某个方法为什么慢一般都是三步走1、通过arthas的trace命令首先找到性能较差的具体方法如果访问量比较大建议设置最小的耗时精确的找到耗时比较高的调用。2、通过watch命令查看此调用的参数和返回值重点是参数这样就可以在开发环境或者测试环境模拟类似的现象通过debug找到具体的问题根源。3、使用stop命令将所有增强的对象恢复。一般来说watch只是用来看参数用的watch io.xx.service.query.ChooseQueryService getData ‘{params, returnObj}’ ‘#cost1’ -x 4 --exclude-class-pattern ‘EnhancerBySpringCGLIB’trace io.xx.controller.query.ChooseQueryController getData ‘params[0].queryCode“0011”’ ‘‘里写条件如果不清楚可以用watch先看看完后在加写多个条件就’params[0].queryCode’‘0011’’ params[0].size15‘trace --skipJDKMethod false io.dataease.service.query.ChooseQueryService getData ‘#cost1’ 只保留 耗时 1ms 的调用 同时连JDK 方法也一起追踪。使用arthas监控sql执行时长watch org.apache.ibatis.executor.statement.PreparedStatementHandler query‘{target.boundSql.sql, target.parameterHandler.parameterObject, #cost}’‘#cost1’ -x 2 -s动态trace增强方法首先第一个终端进行你要监控的方法trace io.dataease.controller.query.ChooseQueryController getData params[0].queryCode0011’在开一个终端监听子方法trace io.dataease.service.query.ChooseQueryService getData --listenerId 3这里的id要和上面的id一样就可以在上面的参数限制下继续监听当前条件

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…