一次典型的Memroy Leak的跟踪学习过程

一次,典型,memroy,leak,跟踪,学习,过程 · 浏览次数 : 155

小编点评

**CPU占用问题分析** **问题:** 项目在 QQ 群里说它的系统出现了 CPU占用较高的情况。TOP 查看发现大部分占用 CPU 的都是 Java 核心进城后附近的进程。 **分析结果:** - 首先怀疑是 FullGC 问题。 - 然后群里反馈了 dump 和 tracelog 等内容进行了简单的分析,发现 12 个 GC 进程正在运行。 - 每个 GC 进程占用约 4GB 的内存,其中包含了对象、方法和字段的信息。 - 12 个 GC 进程的运行时间约为 4 个小时。 **结论:** - 问题可能是由于 GC 进程由于内存泄漏导致的。 - 12 个 GC 进程占用大量内存,这可能导致系统性能下降。 - 优化 GC 进程的配置可以减少内存占用。

正文

背景

周四时某项目在QQ群里说自己的系统出现了CPU占用较高的情况.
TOP 查看发现大部分占用CPU的都是 JAVA核心进城后附近的进程.
所以初步怀疑 是出现了FullGC的问题. 
然后群里反馈了dump 以及 tracelog等内容
进行了简单的分析, 这里总结一下, 备忘

关于GC进程

java -jar 进行启动服务时
第一个进程是核心进程.
第二个一般是 DestroyVM的进程.
然后CPU核心个数的进程一般是GC进程.

查看办法一般为: Top 然后输入  大写 P 按照CPU使用率进行排序.
比如本次给出来的 jstack的处理
进程号是: 89622
然后可以获取 16进制的 编码为: printf +%x 89622
结果为: 15e16
文件搜索 15e17 
进程信息为:
"DestroyJavaVM" #487 prio=5 os_prio=0 tid=0x00007f4e2b411000 nid=0x15e17
其他的GC进程为:
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f4f4001f800 nid=0x15e18
因为有 12个CPU 所以就会有12个GC进程. 
然后就会再有一个VM的进程
"VM Thread" os_prio=0 tid=0x00007f4f40272000 nid=0x15e25 runnable 
然后会有 : Reference Handler 和 Finalizer 以及 Signal Dispatcher 三个JVM的进程
然后后面就是 C1和C2的编译进程了 

关于GC进程

大部分可以通过简单的10进制和16进制转换就可以简单看出来 哪些进程有问题. 

GC进程多说明堆区存在问题, 有内存泄露或者是大对象, 或者是配置较低.
如果是编译进程较多, 可能是CodeCache存在异常配置. 

不同占用CPU的情况是不一样的 可以进行一些简单的分析和定位.

关于dump分析

使用mat分析即可,这个非常简单.
然后打开 dominator tree的方式可以 查看哪些内存占用较多.
也可以直接打开 memory leak detect的来进行判断

本次发现一个比较诡异的数据
org.springframework.data.redis.connection.util.ByteArrayWrapper
这个名称的对象有 四千万个. 
占用内存大约  4G左右
感觉打个对象占用100bytes的字节进行计算
4千万*100bytes = 40M*0.1KB = 4GB
与结果完全一致, 基本上发现了内存泄漏的点

然后告诉不重启服务 第二天再次抓取dump
发现内存对象从3.75千万到了4.05千万
工作时间大约也就4个小时不到战胜了 300万行记录
计算一周时间. (40/4)*0.3千万=3千万记录
基本上符合数据的情况. 也明确了内存泄漏的点. 

一个另外的思路

抓取dump进行分析需要mat工具并且抓取和下载,以及分析都比较耗时.
感觉这一块 是可以优化的.
然后使用抓取内存对象数目的方式进行验证:
jcmd $pid GC.class_histogram -all >zhaobsh.txt

然后搜索 org.springframework.data.redis.connection.util.ByteArrayWrapper 查看变量数据.
 num     #instances         #bytes  class name
   3:      33433500      802404000  org.springframework.data.redis.connection.util.ByteArrayWrapper
逐个进行分析
第一个数字  代表他的对象数目排第三位.
第二个数字  代表元素的总数量. 这里面是三千三百万. 
第三个数字  是占用的内存大小. (不一定是最终大小.)

这个命令只需要三秒钟就可以查询出结果. 比dump要简单非常多.
感觉可以在操作命令前后进行两次跟踪就可以判断补丁的修改是否凑效了. 

与一次典型的Memroy Leak的跟踪学习过程相似的内容:

一次典型的Memroy Leak的跟踪学习过程

背景 周四时某项目在QQ群里说自己的系统出现了CPU占用较高的情况. TOP 查看发现大部分占用CPU的都是 JAVA核心进城后附近的进程. 所以初步怀疑 是出现了FullGC的问题. 然后群里反馈了dump 以及 tracelog等内容 进行了简单的分析, 这里总结一下, 备忘 关于GC进程 ja

一次JVM GC长暂停的排查过程

在高并发下,Java程序的GC问题属于很典型的一类问题,带来的影响往往会被进一步放大。不管是「GC频率过快」还是「GC耗时太长」,由于GC期间都存在Stop The World问题,因此很容易导致服务超时,引发性能问题。

一次JVM GC长暂停的排查过程

作者:京东科技 徐传乐 背景 在高并发下,Java程序的GC问题属于很典型的一类问题,带来的影响往往会被进一步放大。不管是「GC频率过快」还是「GC耗时太长」,由于GC期间都存在Stop The World问题,因此很容易导致服务超时,引发性能问题。 事情最初是线上某应用垃圾收集出现Full GC异

[转帖]一次 Java 进程 OOM 的排查分析(glibc 篇)

https://juejin.cn/post/6854573220733911048 遇到了一个 glibc 导致的内存回收问题,查找原因和实验的的过程是比较有意思的,主要会涉及到下面这些: Linux 中典型的大量 64M 内存区域问题 glibc 的内存分配器 ptmalloc2 的底层原理 如

[转帖]一次 Java 进程 OOM 的排查分析(glibc 篇)

https://juejin.cn/post/6854573220733911048 遇到了一个 glibc 导致的内存回收问题,查找原因和实验的的过程是比较有意思的,主要会涉及到下面这些: Linux 中典型的大量 64M 内存区域问题 glibc 的内存分配器 ptmalloc2 的底层原理 如

架构与思维:微服务架构的思想本质

我们为什么需要微服务架构,它一定是为了解决我们某些问题才出现了。这篇文章我们讨论下微服务架构模式所解决的问题,带来的挑战,以及他的核心思想本质。 1 早期的服务架构 上图是一个典型的服务分层架构: Client: 调用方是browser web或者App 应用层: 实现计算层的业务逻辑,从上游数据层

Dubbo架构设计与源码解析(二) 服务注册

作者:黄金 一、Dubbo简介 Dubbo是一款典型的高扩展、高性能、高可用的RPC微服务框架,用于解决微服务架构下的服务治理与通信问题。其核心模块包含 【RPC通信】 和 【服务治理】 ,其中服务治理又分为服务注册与发现、服务容错、负载均衡、流量调度等。今天将重点介绍Dubbo的服务注册与发现。

固定型思维 VS 成长型思维

回顾进入职场工作以来,对比曾经的学生时代,如果让我讲一个对自己影响最大的改变,那就是思维模式的一个转变。 具体来说,就是从一个典型的固定型思维转变成一个具备有成长型思维的人。 当然,我不敢妄称自己已经是全面的成长型思维,但我的的确确已经意识到成长型思维的好处。 最起码,我可以不再像曾经学生时代的那个

抖音面试:说说延迟任务的调度算法?

Netty 框架是以性能著称的框架,因此在它的框架中使用了大量提升性能的机制,例如 Netty 用于实现延迟队列的时间轮调度算法就是一个典型的例子。使用时间轮调度算法可以实现海量任务新增和取消任务的时间度为 O(1),那么什么是时间轮调度算法呢?接下来我们一起来看。 1.延迟任务实现 在 Netty

快速上手python的简单web框架flask

简介 python可以做很多事情,虽然它的强项在于进行向量运算和机器学习、深度学习等方面。但是在某些时候,我们仍然需要使用python对外提供web服务。 比如我们现在有一个用python写好的模型算法,这个模型算法需要接收前端的输入,然后进行模拟运算,最终得到最后的输出。这个流程是一个典型的web