JVM诊断及工具笔记(2)使用arthas定位哪里执行了System#gc()

笔者是汽车之家实时计算平台的一名小伙伴。负责flink平台,数据湖及kafka平台的设计与开发。平时擅长做平台设计,定位及解决各种疑难杂症。第二篇文章,讲的点依旧很小,但是这次图多!!! 在这里感谢支持上篇文章的小伙伴了
前言
这篇文章是之前解决一个Flink任务在线上发生fullgc

当时的想法就是fullgc发生在:
堆内存: 通过堆内存监控和dump堆内存这两种方式 都发现堆占用不大 ,排除
metaspace: gc日志里并没有堆metaspace日志且metaspace占用很小 ,排除
因此主要把排除重点放在直接内存。接下来老规矩,我们长话短说会夹带一点点心路历程。
步骤
1.配置jvm参数打印gc
clusterConf.env.java.opts=-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:${LOG_DIRS}/gc.log
2.在gc日志里发现有程序主动调用System.gc()

当时猜测是使用的flink11版本代码里面会有调用

加了些日志,发现并没有调用。
3.使用arthas
3.1.下载 arthas,并attach需要监听的jvm进程
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar

3.2.监听 System.gc()方法并把日志打到磁盘上
options unsafe true
stack java.lang.System gc -n 1 >> /tmp/gc.log &

3.3 观察日志
过了一段时间 观察下日志发现

是在Kafka connector 调用java的nio的时候调用的System.gc()
4.分析
4.1讲一下这块代码的大致背景
java的直接内存(direct memory)是不会被gc回收的,而是通过监听持有直接内存资源的对象被回收的时候才把直接内存释放掉的。主要原理使用到虚引用和引用队列:当jvm发现对象已经没有强引用,仅剩虚引用时会将其存放在Reference的discovered的列表中 --->随后变成Pending状态 (准备加入引动队列) ---->随后进入Enqueued状态(加入队列,监听者可以获取从而回收资源)
4.2背景介绍完毕,回到刚才找到的方法栈,看倒数第二个方法

栈里 DirectByteBuffer 这个类就是直接内存资源的持有者。

DirectByteBuffer 在构造时便被Cleaner监听回收资源。束于篇幅稍微文字介绍下Cleaner, Cleaner 就是 PhantomReference(虚引用)的子类。 1.Cleaner#create的方法就是将DirectByteBuffer对象虚引用且监听引用队列,2.当在队列中接收到DirectByteBuffer(此时对象已经被jvm标记discovered) 执行Deallocator的回收资源操作。
4.3 倒数第一个方法


来到倒数第一个方法,打开实现大家应该就能明白,这个方法是给DirectByteBuffer预留资源的。如果资源充足,万事大吉。如果资源充足: 大家回忆下刚才说讲的被虚引用DirectByteBuffer的discovered,pending,enqueued状态, 图中我用箭头标记的jlra.tryHandlePendingReference() 是尽快将pending状态的对象尽快转换成enqueued状态被好被Cleaner回收掉。一顿操作过后发现资源依旧不够。那么只能调用System.gc() 方法执行fullgc了。
注: 这套实现中 使用fullgc的好处是有部分 DirectByteBuffer对象很多次回收不掉进入老年代之后,这个时候young gc是没有办法回收掉的。
5.总结
刚才分析那么多,其实总结起来就一句话:直接内存不够了。回头又看了下用户任务的特点。发现数据消费量很大,但是代码可用的直接内存不多,反倒是框架可用的直接内存(taskmanager.memory.framework.off-heap.size)设得很大。合理调节完资源后,这个任务就再也没有发生oom了。
JVM诊断及工具笔记(2)使用arthas定位哪里执行了System#gc()的更多相关文章
- JVM诊断及工具笔记(4) 使用visualvm分析JVM堆内存泄漏
在这里感谢最近一直阅读我文章的小伙伴,如果觉得文章对你有用,可以帮忙关注转载,需要的时候可以及时找到文章. 背景 今年Q3季度我们在推广业务方使用Iceberg,当时为了让不同业务线的用户可以使用自己 ...
- JVM调优工具锦囊
Arthas线上 分析诊断调优工具 以前我们要排查线上问题,通常使用的是jdk自带的调优工具和命令.最常见的就是dump线上日志,然后下载到本地,导入到jvisualvm工具中.这样操作有诸多不变,现 ...
- jvm系列(七):jvm调优-工具篇
16年的时候花了一些时间整理了一些关于jvm的介绍文章,到现在回顾起来还是一些还没有补充全面,其中就包括如何利用工具来监控调优前后的性能变化.工具做为图形化界面来展示更能直观的发现问题,另一方面一些耗 ...
- Java虚拟机(六):JVM调优工具
工具做为图形化界面来展示更能直观的发现问题,另一方面一些耗费性能的分析(dump文件分析)一般也不会在生产直接分析,往往dump下来的文件达1G左右,人工分析效率较低,因此利用工具来分析jvm相关问题 ...
- JVM调优-工具篇
原文地址 16年的时候花了一些时间整理了一些关于jvm的介绍文章,到现在回顾起来还是一些还没有补充全面,其中就包括如何利用工具来监控调优前后的性能变化.工具做为图形化界面来展示更能直观的发现问题,另一 ...
- 性能测试之JVM的故障分析工具VisualVM
VisualVM 是随JDK一同发布的jvm诊断工具,通过插件可以扩展很多功能,插件扩展也是其精华所在. 提供了一个可视界面,用于在Java应用程序在Java虚拟机上运行时查看有关Java应用程序的详 ...
- [转]Oracle10g数据库自动诊断监视工具(ADDM)使用指南
第一章 ADDM简介 在Oracle9i及之前,DBA们已经拥有了很多很好用的性能分析工具,比如,tkprof.sql_trace.statspack.set even ...
- Capsule:开源的 JVM 应用部署工具
[编者按]本文作者 Ron Pressler 是 Parallel Universe 公司的创始人,拥有着丰富的高性能开发经验.通过这篇文章,Ron 向大家详细介绍了全新的开源 JVM 部署工具--C ...
- 《深入理解Java虚拟机》(五)JVM调优 - 工具
JVM调优 - 工具 JConsole:Java监视与管理控制台 JConsole是一个机遇JMX(Java Management Extensions,即Java管理扩展)的JVM监控与管理工具,监 ...
随机推荐
- 【LeetCode】761. Special Binary String 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/special- ...
- A. Points on Line
A. Points on Line time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- Redis的各种实现(Jedis、Redisson、Lettuce)
1.1.Jedis 是Redis的Java实现的客户端.支持基本的数据类型如:String.Hash.List.Set.Sorted Set. 特点:使用阻塞的I/O,方法调用同步,程序流需要等到so ...
- Obfuscated Gradients Give a False Sense of Security: Circumventing Defenses to Adversarial Examples
目录 概 主要内容 Obfuscated Gradients BPDA 特例 一般情形 EOT Reparameterization 具体的案例 Thermometer encoding Input ...
- 图像处理opencv-Rect 排序、合并[转]
opencv进行rect检测时,当检测到多个rect,组成rect vector之后,有些rect是由一个区域误分割得到的, 可以按照某种规格将这些rect合并为一个rect.比如按照x,y,widt ...
- 编写Java程序,使用 Java 的 I/O 流将 H:\eclipse.zip 文件拷贝至 E 盘下,重新命名为 eclipse 安装 .zip。
查看本章节 查看作业目录 需求说明: 使用 Java 的 I/O 流将 H:\eclipse.zip 文件拷贝至 E 盘下,重新命名为 eclipse 安装 .zip.在拷贝过程中,每隔2000 毫秒 ...
- 【】(Git)用动图展示10大Git命令
1.说明 git merge.git rebase.git reset.git revert.git fetch.git pull.git reflog-- 你知道这些 git 命令执行的究竟是什么任 ...
- STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解)
目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) 前面 ...
- linux 之 nginx安装步骤
配置规划 用户 lzh 用户目录 /lzh 下载 进入官网下载nginx http://nginx.org/download/ 安装 解压 cd /lzh/app tar -zxvf nginx-1 ...
- JDK_win10环境下安装JDK8时点击下一步没反应的解决办法
问题现象 打开JDK8,点击下一步就没后续了... 解决方法 百度了一下"win10安装jdk8点下一步无响应" . 按照博客中说的操作试了下...安装成功了... 只想说...什 ...