版权说明: 本文章版权归本人及博客园共同所有,转载请在文章前标明原文出处( 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内存泄露分析过程的更多相关文章

  1. Java内存泄露分析和解决方案及Windows自带查看工具

    Java内存泄漏是每个Java程序员都会遇到的问题,程序在本地运行一切正常,可是布署到远端就会出现内存无限制的增长,最后系统瘫痪,那么如何最快最好的检测程序的稳定性,防止系统崩盘,作者用自已的亲身经历 ...

  2. JAVA内存泄露分析及解决

    一,问题产生     项目采用Tomcat6.0为服务器,数据库为mysql5.1,数据库持久层为hibernate3.0,以springMVC3.0为框架,项目开发完成后,上线前夕进行稳定性拷机,测 ...

  3. 使用Eclipse Memory Analyzer 进行JAVA内存泄露分析

    一,安装 Eclipse Memory Analyzer 在Memory Analyzer的官网找到 update site的地址:

  4. Java 内存泄露的理解与解决过程

    本文详细地介绍了Java内存管理的原理,以及内存泄露产生的原因,同时提供了一些列解决Java内存泄露的方案,希望对各位Java开发者有所帮助. Java内存管理机制 在C++ 语言中,如果需要动态分配 ...

  5. java内存泄露的理解与解决(转)

    Java内存管理机制 在C++语言中,如果需要动态分配一块内存,程序员需要负责这块内存的整个生命周期.从申请分配.到使用.再到最后的释放.这样的过程非常灵活,但是却十分繁琐,程序员很容易由于疏忽而忘记 ...

  6. 学会用Clang来进行内存泄露分析

    最近项目出现了内存泄露的问题,对于PC x86平台来说,一点点的内存泄露往往不会出错,很难进行debug调试.这个时候我们可以用到苹果给我们带来的神器--Clang编译器来进行内存泄露分析检测,开关打 ...

  7. Java内存泄漏分析系列之五:常见的Thread Dump日志案例分析

    原文地址:http://www.javatang.com 症状及解决方案 下面列出几种常见的症状即对应的解决方案: CPU占用率很高,响应很慢 按照<Java内存泄漏分析系列之一:使用jstac ...

  8. Java内存泄漏分析系列之二:jstack生成的Thread Dump日志结构解析

    原文地址:http://www.javatang.com 一个典型的thread dump文件主要由一下几个部分组成: 上图将JVM上的线程堆栈信息和线程信息做了详细的拆解. 第一部分:Full th ...

  9. 关于java内存泄露的总结--引用的类型:强引用,弱引用,软引用

    今天面试了一家公司的java开发方面的实习生,被问到一个问题:如何处理java中的内存泄露问题,保证java的虚拟机内存不会被爆掉,当时其实觉得面试官的问题有点泛,所以也没有很好领会他的意思,答案也不 ...

  10. Java内存泄露原因详解

    一.Java内存回收机制 不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址.Java中对象是采用new或者反射的方法创建的, 这些对象的创建都是在堆(He ...

随机推荐

  1. 如何深度学习Python?

    安装必要软件:首先需要安装Anaconda或Miniconda等科研计算环境,并创建虚拟环境以便管理不同项目所需库和版本.可以按照如下步骤进行操作: 下载并安装 Anaconda 或 Minicond ...

  2. 重学Java(一):什么是对象

    前言 本系列文章内容来自于<Thinking in Java>作者的最新续作<On Java>基础卷,作者根据最新 Java 8.11.17的内容,重讲了Java的编程思想,值 ...

  3. Pooling与马赛克的秘密

      说到Pooling,相信学习过CNN的朋友们都不会感到陌生.Pooling在中文当中的意思是"池化",在神经网络当中非常常见,通常用的比较多的一种是Max Pooling,具体 ...

  4. Java 删除PDF页面 (免费工具分享)

    对PDF页面的增删通常需要借助专门的工具,而这些工具一般需要付费才能使用.那么我们可以通过Java代码免费实现这一功能吗?答案是肯定的.这篇文章就教大家如何使用一个免费的国产Java库来删除PDF中的 ...

  5. Linux驱动开发笔记(五):驱动连接用户层与内核层的文件操作集原理和Demo

    前言   驱动写好后,用户层使用系统函数调用操作相关驱动从而实现与系统内核的关联,本篇主要就是理解清楚驱动如何让用户编程来实现与内核的交互.   杂项设备文件操作集 cd /usr/src/linux ...

  6. going 小闫 | 学习就像典韦哥:彻底疯狂

    看了相关的Hadoop的视频,介绍部分. 刷单词 看了coco电影

  7. JAVA学习week2

    这周:根据老师在群里面推荐的JAV学习路线,初步规划了一下学习方案 并找到了相关的视频,目前来说在学习SE.学习内容:环境变量的配置和简单的hello world程序书写的注意点 下周:打算进行简单的 ...

  8. 2020ICPC上海 C题(数位dp, 记忆化搜索)

    先复习了下之前做的数位DP又做了道新题才看的这道题,对我来说还是一种新类型,涉及到非线性计算,之前做的都是形如 \(dp[x]-dp[y]\)这样的只用处理一个上限做下差即可.一开始想分别枚举 \(x ...

  9. CortexM外设:NVIC 嵌套向量中断控制器

    优先级分组Priority Group 使能Enabled 抢占优先级Preemption Priority 子优先级Sub Priority 外部中断线 EXTI Line 定时器中断 TIM1 u ...

  10. dubbo优化

    dubbo 的优化配置 在spring整合的配置文件中配置1. 超时配置在消费方调用服务方接口服务时,会发生如下超时错误,Dubbo消费方在调用服务时,超时时间默认是1000毫秒,这个时间可能比较短, ...