笔者是汽车之家实时计算平台的一名小伙伴。负责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()的更多相关文章

  1. JVM诊断及工具笔记(4) 使用visualvm分析JVM堆内存泄漏

    在这里感谢最近一直阅读我文章的小伙伴,如果觉得文章对你有用,可以帮忙关注转载,需要的时候可以及时找到文章. 背景 今年Q3季度我们在推广业务方使用Iceberg,当时为了让不同业务线的用户可以使用自己 ...

  2. JVM调优工具锦囊

    Arthas线上 分析诊断调优工具 以前我们要排查线上问题,通常使用的是jdk自带的调优工具和命令.最常见的就是dump线上日志,然后下载到本地,导入到jvisualvm工具中.这样操作有诸多不变,现 ...

  3. jvm系列(七):jvm调优-工具篇

    16年的时候花了一些时间整理了一些关于jvm的介绍文章,到现在回顾起来还是一些还没有补充全面,其中就包括如何利用工具来监控调优前后的性能变化.工具做为图形化界面来展示更能直观的发现问题,另一方面一些耗 ...

  4. Java虚拟机(六):JVM调优工具

    工具做为图形化界面来展示更能直观的发现问题,另一方面一些耗费性能的分析(dump文件分析)一般也不会在生产直接分析,往往dump下来的文件达1G左右,人工分析效率较低,因此利用工具来分析jvm相关问题 ...

  5. JVM调优-工具篇

    原文地址 16年的时候花了一些时间整理了一些关于jvm的介绍文章,到现在回顾起来还是一些还没有补充全面,其中就包括如何利用工具来监控调优前后的性能变化.工具做为图形化界面来展示更能直观的发现问题,另一 ...

  6. 性能测试之JVM的故障分析工具VisualVM

    VisualVM 是随JDK一同发布的jvm诊断工具,通过插件可以扩展很多功能,插件扩展也是其精华所在. 提供了一个可视界面,用于在Java应用程序在Java虚拟机上运行时查看有关Java应用程序的详 ...

  7. [转]Oracle10g数据库自动诊断监视工具(ADDM)使用指南

    第一章 ADDM简介                 在Oracle9i及之前,DBA们已经拥有了很多很好用的性能分析工具,比如,tkprof.sql_trace.statspack.set even ...

  8. Capsule:开源的 JVM 应用部署工具

    [编者按]本文作者 Ron Pressler 是 Parallel Universe 公司的创始人,拥有着丰富的高性能开发经验.通过这篇文章,Ron 向大家详细介绍了全新的开源 JVM 部署工具--C ...

  9. 《深入理解Java虚拟机》(五)JVM调优 - 工具

    JVM调优 - 工具 JConsole:Java监视与管理控制台 JConsole是一个机遇JMX(Java Management Extensions,即Java管理扩展)的JVM监控与管理工具,监 ...

随机推荐

  1. 【LeetCode】160. Intersection of Two Linked Lists 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 双指针 栈 日期 题目地址:https://leet ...

  2. 【LeetCode】39. Combination Sum 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:递归 方法二:回溯法 日期 题目地址:[htt ...

  3. idea使用教程-模板的使用

    一.代码模板是什么 它的原理就是配置一些常用代码字母缩写,在输入简写时可以出现你预定义的固定模式的代码,使得开发效率大大提高,同时也可以增加个性化.最简单的例子就是在Java中输入sout会出现Sys ...

  4. 【python】QT5 cvimg 转 pixmap

    自己乱搞了一个 import cv2 from PIL import Image imageRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) im = Image. ...

  5. JUC之线程间的通信

    线程通信 视频1: 2021.12.18 JUC视频学习片段 对上次多线程编程步骤补充(中部): 创建资源类,在资源类中创建属性和操作方法 在资源类里面操作 判断 干活 通知 创建多个线程,调用资源类 ...

  6. Java初学者作业——定义客户类(Customer),客户类的属性包括:姓名、年龄、电话、余额、账号和密码;方法包括:付款。

    返回本章节 返回作业目录 需求说明: 定义客户类(Customer),客户类的属性包括:姓名.年龄.电话.余额.账号和密码:方法包括:付款. 实现思路: 定义 Customer 类,并添加姓名.余额. ...

  7. CS基础 float 浮动的使用方法

    html代码: <body> <div class='red'> </div> <div class='green'> </div> < ...

  8. Python_类型转换

    列表与字符串互相转换 join方法将list转换为string _list = ["a", "b", "c"] # 以".&quo ...

  9. celery起动,运行有警告

    运行命令 :  celery worker -A task_log -l info: 有如下警告 2019-12-22 22:42:50,215: WARNING/MainProcess] /root ...

  10. 基于ShardingJDBC的分库分表及读写分离整理

    ShardingJDBC的核心流程主要分成六个步骤,分别是:SQL解析->SQL优化->SQL路由->SQL改写->SQL执行->结果归并,流程图如下: sharding ...