笔者是汽车之家实时计算平台的一名小伙伴。负责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】633. Sum of Square Numbers 解题报告(python & Java & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 双指针 列表生成式 循环 日期 题目地址:https ...

  2. 【LeetCode】278. First Bad Version 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 二分查找 日期 题目地址:https://leetcode.c ...

  3. B. Destroying Roads

    Destroying Roads 题目链接 题意 n个点,m条边每两个点之间不会有两个相同的边,然后给你两个起s1,s2和终点t1,t2; 求删除最多的边后满足两个s1到t1距离\(<=l1\) ...

  4. 【LeetCode】844. Backspace String Compare 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字符串切片 栈 日期 题目地址:https://le ...

  5. Sum Of Gcd(hdu 4676)

    Sum Of Gcd Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total ...

  6. PowerShell【变量篇】

    PS C:\Users\Administrator> $str='这是一个变量' PS C:\Users\Administrator> $str 这是一个变量 PS C:\Users\Ad ...

  7. mysql 的 if 和 SQL server 的 iif

    在sql语句中,mysql 使用 if 而SQL server 使用iif 如 mysql : SELECT IF(1<2,'yes ','no'); sql server: SELECT II ...

  8. 实验 4 :Open vSwitch 实验 —— Mininet 中使用 OVS 命令

    实验 4 :Open vSwitch 实验 -- Mininet 中使用 OVS 命令 一.实验目的 Mininet 安装之后,会连带安装 Open vSwitch,可以直接通过 Python 脚本调 ...

  9. PPT文档学习小练习链接

    1. <初识PPT2010> https://www.toutiao.com/i6486689592241029645/ 2. <PowerPoint2010实现折线图动态展示> ...

  10. 07.python函数作用域global、nonlocal、LEGB

    函数作用域 作用域 一个标识符的课件范围,这就是标识符的作用域,一般常说的是变量的作用域 def foo():    x = 100 print(x) # 可以访问到吗 上例中x不可以访问到,会抛出异 ...