记录一次Java内存泄露分析过程
版权说明: 本文章版权归本人及博客园共同所有,转载请在文章前标明原文出处( https://www.cnblogs.com/mikevictor07/p/13032635.html ),以下内容为个人理解,仅供参考。
一、背景
最近在集成一个调用链客户端jaeger client(一种opentracing的实现)集成到自定义的SDK中,我们需要增加一种特性:能通过远端服务动态更新采样的参数。
按照jaeger的实现,如果关键参数(比如队列大小、buffer冲刷间隔等)的变动【必须重新建立一个比较重的Tracer】(可以理解为一个给上层调用的对象,无需了解细节),
按照多年的直觉(老油条),这个Tracer大对象的创建成本高,有泄露的可能。
二、使用方法
按照调用规范,我们的重建tracer这个对象后对旧的tracer进行close,源码如下:
/**
* Shuts down the {@link Reporter} and {@link Sampler}
*/
@Override
public void close() {
reporter.close();
sampler.close();
}
按理说调用close即可。
三、验证步骤
在这里使用了JProfiler来调试,启用应用后模拟每秒钟创建一次tracer,并且创建后关闭原先的tracer,然后通过JProfiler的Live Memory观察如下:

这里使用tracer这个关键词过滤信息快速找到相关对象,在点击上图的【Run GC】按钮后其他对象能回收,只有排名前两个对象无法进行回收,
说明它们存在强引用无法GC,而且数量一直在增长,右键第一行,选择【Show Select In Heap Walker】,如下:

选择进去后提示是否dump内存分析(若应用占用内存较大无法本地dump,可用memory analyzer tool继续dump hprof文件分析):

从references分析有哪些引用,结果如下:

从这里基本可以看出是JVM的shutdown hook强引用,我们再源码查找showdown hook的调用,结果如下:
if (builder.manualShutdown || runsInGlassFish()) {
log.info("No shutdown hook registered: Please call close() manually on application shutdown.");
} else {
// register this tracer with a shutdown hook, to flush the spans before the VM shuts down
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
JaegerTracer.this.close();
}
});
}
由于默认没有开启manual shutdown,jaeger为了应用停止时能close(内部主要是冲刷数据到agent)加了此特性。
四、修复与总结
修复方法很简单,将manual shutdown配置为true,并且自行实现关闭钩子即可(在我们的应用中是将tracer根据服务名put到map中,后一次对象将覆盖前一个,最后循环map关闭)。
本文章展示了使用jprofile来分析一次内存泄露的过程,如果对生产的memory分析,建议dump hprof文件到本地。
启动参数加上-XX:+HeapDumpOnOutOfMemoryError 以便保留当时内存快照,如果发生OOM后JVM杀掉触发OOM的线程,部分内存也被回收,事后分析的dump文件可能已经没有了原先到OOM的数据,只能等下一次发生,但有些情况几个月才发生一次,建议预先配置。
记录一次Java内存泄露分析过程的更多相关文章
- Java内存泄露分析和解决方案及Windows自带查看工具
Java内存泄漏是每个Java程序员都会遇到的问题,程序在本地运行一切正常,可是布署到远端就会出现内存无限制的增长,最后系统瘫痪,那么如何最快最好的检测程序的稳定性,防止系统崩盘,作者用自已的亲身经历 ...
- JAVA内存泄露分析及解决
一,问题产生 项目采用Tomcat6.0为服务器,数据库为mysql5.1,数据库持久层为hibernate3.0,以springMVC3.0为框架,项目开发完成后,上线前夕进行稳定性拷机,测 ...
- 使用Eclipse Memory Analyzer 进行JAVA内存泄露分析
一,安装 Eclipse Memory Analyzer 在Memory Analyzer的官网找到 update site的地址:
- Java 内存泄露的理解与解决过程
本文详细地介绍了Java内存管理的原理,以及内存泄露产生的原因,同时提供了一些列解决Java内存泄露的方案,希望对各位Java开发者有所帮助. Java内存管理机制 在C++ 语言中,如果需要动态分配 ...
- java内存泄露的理解与解决(转)
Java内存管理机制 在C++语言中,如果需要动态分配一块内存,程序员需要负责这块内存的整个生命周期.从申请分配.到使用.再到最后的释放.这样的过程非常灵活,但是却十分繁琐,程序员很容易由于疏忽而忘记 ...
- 学会用Clang来进行内存泄露分析
最近项目出现了内存泄露的问题,对于PC x86平台来说,一点点的内存泄露往往不会出错,很难进行debug调试.这个时候我们可以用到苹果给我们带来的神器--Clang编译器来进行内存泄露分析检测,开关打 ...
- Java内存泄漏分析系列之五:常见的Thread Dump日志案例分析
原文地址:http://www.javatang.com 症状及解决方案 下面列出几种常见的症状即对应的解决方案: CPU占用率很高,响应很慢 按照<Java内存泄漏分析系列之一:使用jstac ...
- Java内存泄漏分析系列之二:jstack生成的Thread Dump日志结构解析
原文地址:http://www.javatang.com 一个典型的thread dump文件主要由一下几个部分组成: 上图将JVM上的线程堆栈信息和线程信息做了详细的拆解. 第一部分:Full th ...
- 关于java内存泄露的总结--引用的类型:强引用,弱引用,软引用
今天面试了一家公司的java开发方面的实习生,被问到一个问题:如何处理java中的内存泄露问题,保证java的虚拟机内存不会被爆掉,当时其实觉得面试官的问题有点泛,所以也没有很好领会他的意思,答案也不 ...
- Java内存泄露原因详解
一.Java内存回收机制 不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址.Java中对象是采用new或者反射的方法创建的, 这些对象的创建都是在堆(He ...
随机推荐
- vue通过地址下载文件
通过a标签 // 创建a标签 const link = document.createElement('a') // download属性 link.setAttribute('download', ...
- 【python】无法安装pip,报错ImportError: No module named 'pip'解决方案
命令提示符输入以下代码即可 python -m ensurepip
- 向“创新者”升阶,程序员当下如何应对 AI 的挑战
随着 AI 技术的飞速发展,特别是大模型的出现,传统的程序员角色正在经历深刻的变革,我们不得不重新对自己进行审视和思考. 通用领域大模型的"泛化能力" 在过去的二十年内,AI 领域 ...
- Vue3+Vue-Router+TypeScript+Vite+Element-Plus+Axios+Pinia快速搭建开发框架
1.环境准备 (1) 首先你得需要安装node和npm 2.环境初始化 (1) 先随意找个文件夹,初始化vite # 安装pnpm npm i -g pnpm # 初始化vite pnpm creat ...
- Redis工具类及Redis序列化
导入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>sp ...
- 数字孪生结合GIS系统为物流行业带来的改变
随着全球物流业务不断扩张和发展,数字化转型成为当今物流行业的主要趋势.在这个数字化时代,数字孪生技术和地理信息系统(GIS)的结合,为物流行业带来了前所未有的机遇和挑战.这种融合将为物流企业提供更高效 ...
- SSM整合 tomcat报错: <严重 [RMI TCP Connection(22)-127.0.0.1] org.apache.catalina.core.StandardContext.startInternal 一个或多个筛选器启动失败。完整的详细信息将在相应的容器日志文件中找到>
前提:学了一个暑假 从Javaweb -> mybits ->spring -> spring-mvc 打算跟着网上ssm整合项目做一个项目 在完成最后一步spring对spring ...
- STM32CubeMX教程10 RTC 实时时钟 - 周期唤醒、闹钟A/B事件和备份寄存器
本实验主要使用STM32CubeMX软件配置STM32F407开发板实现RTC周期唤醒.闹钟A/B事件功能,周期唤醒中输出RTC时间,闹钟A/B事件发生时利用串口输出闹钟A/B事件发生提示 1.准备材 ...
- 文心一言 VS 讯飞星火 VS chatgpt (47)-- 算法导论6.1 5题
五.一个已排好序的数组是一个最小堆吗? 文心一言: 一个已排好序的数组不一定是一个最小堆.最小堆是一种特殊的二叉树,它满足以下性质:对于任意节点 x,其父节点 y 的值都小于等于 x 的值.而一个已排 ...
- SHA加密解密
一.概述 SHA(Secure Hash Algorithm,安全哈希算法)是一类广泛应用于加密领域的算法,主要用于数据完整性校验和加密认证.SHA算法首次出现在1993年,由美国国家安全局(NSA) ...