线上环境频繁GC问题排查,Finalizer对象该背这个锅吗?
问题描述
公司的一个SpringMVC服务,最近在做运维检查的时候发现young gc 和 full gc太频繁,远远超过了正常情况。服务器配置是4核8G,该服务分配了6G内存。通过arthas的dashboard统计情况在20个小时之内发生的young gc和 full gc 次数,如下图:young gc 393次,full gc 19次
问题排查
- 在eden区达到80%的时候,通过arthas 的 heapdump dupm了堆内存文件
java -jar arthas-boot.jar
挂载对应的应用的PID,进入到arthas管理界面
heapdump /tmp/dump.hprof
使用MemoryAnalyzer 分析hprof 文件,发现heap中存在最多的对象就是java.lang.ref.Finalizer 对象,占用了整个空间的47%,如下图
点击Histogram 查看Finalizer对象,右键—>List Objects—> with outgoing reference 查看具体的Finalizer对象,查看图片左下角的referent 就是真正需要回收的垃圾。分析了一部分referent 都是涉及到底层jdk 关于https请求连接的对象。如HtppsURLConnectionIpml,ZipFileInputStream等。
结合线上系统的业务日志发现该服务与第三方系统交互频繁,就是通过原生的jdk 自带的HttpsURLConnection 来发起的请求。那具体是什么原因造成了大量的Finalizer对象堆积呢?
原因就是每次发起请求都会 new HttpURLConnection 对象,请求完毕 该对象及其关联的对象并没有立即释放内存而是进入了ReferenceQueue队列等待Finalizer 的守护线程来回收。如果主线程的请求比较频繁,就会产生大量的Finalizer对象放入到Queue中。而守护线程的优先级是比较低导致回收Finalizer对象的速度远低于主线程产生的速度,这样就导致了eden区内存迅速的被Finalizer对象占满。
为什么这些对象不是直接回收而是进入到Queue等待被守护线程回收呢?那是因为这些对象重写了finalize()方法,导致需要释放的对象被放入到Queue通过守护线程来回收。
HttpsURLConnectionImpl.java
protected void finalize() throws Throwable {this.delegate.dispose();
}
protected void dispose() throws Throwable {super.finalize();
}
解决方案
解决方案就是减少Finalizer对象的产生速度,但是业务访问是不能减少,所以我们就引入了HttpClient 现有的连接池功能,不用每次连接都new 新的对象而是复用连接池中空闲的对象。封装上线后频繁young gc的问题得到了彻底的解决。事后监控基本上几个小时发生一次young gc ,full gc更少了。
总结
- 线上环境需要一定的成熟的APM(应用性能管理) 对企业系统即时监控以实现对应用程序性能管理和故障管理的系统化的解决方案。
- 通过合理搭配工具,提高问题处理能力。
- 经过线上实际问题的处理,加深了对系统底层的了解,对以后问题排查流程更加熟练、更加自信、更加高效。
- 实践是检验巩固技术的唯一真理–诚不欺我。
线上环境频繁GC问题排查,Finalizer对象该背这个锅吗?相关推荐
- 【原创】线上环境 SYN flooding 问题排查
问题描述: 线上环境中,公司自研即时通讯软件不定时掉线. 问题排查: 由运维和测试人员发现并报告,线上环境出现网络异常,具体表现为登录服务器虚拟 IP 地址无法 ping ...
- 生产环境和开发环境_环境部署:开发、测试和线上环境的区别
点击蓝字 关注我们 软件开发环境(Software Development Environment,SDE)是指在基本硬件和宿主软件的基础上,为支持系统软件和应用软件的工程化开发和维护而使用的一组软件 ...
- 面试官:线上环境 FGC 频繁,如何解决?
前言 这个问题应该是 Java 面试中很经常被问到的一个题目,很多人害怕这个题目. 因为大部分人可能在工作中根本遇不到 FGC 频繁的问题,即使从网上背了点答案,心里也不踏实,因为毕竟不是自己亲自接触 ...
- JVM第六讲:线上环境 FGC 频繁,如何解决?
本文是JVM第六讲:线上环境 FGC 频繁,如何解决?重点:得靠经验来解决 文章目录 1.问题背景 2.遇到的问题及解决方案 2.1.pinpoint 打点存在大批量300ms以上 2.2.应用 cp ...
- gc就是fullgc吗 major_线上出现fullgc问题如何排查?
1.问题描述 线上出现fullgc报警,每5分钟一次 2.背景知识 1. 程序执行了System.gc() 执行了jmap -histo:live pid命令 在执行minor gc的时候进行的一系列 ...
- 线上FullGC频繁的排查
线上FullGC频繁的排查 问题 前段时间发现线上的一个dubbo服务Full GC比较频繁,大约每两天就会执行一次Full GC. Full GC的原因 我们知道Full GC的触发条件大致情况有以 ...
- 记几次 [线上环境] Dubbo 线程池占满原因分析(第三次:GC STW)
[线上环境] Dubbo 线程池占满原因排查系列 记几次 [线上环境] Dubbo 线程池占满原因分析(第一次:HttpClient) 记几次 [线上环境] Dubbo 线程池占满原因分析(第二次:C ...
- 登录接口压测响应慢频繁GC问题排查
登录接口压测响应慢频繁GC问题排查 2020.5.22 最近项目组针对几个较重要的接口进行了几十个小时的压测,发现登录接口的压测呈现了一种响应慢且越来越慢的趋势,CPU 也居高不下 压测情况 查看CP ...
- 记一次线上cpu飙升100%的排查过程
大家好,我是烤鸭: 最近没怎么写技术文章,还是得回归下初心,正好前几天出现个线上问题,记录下排查过程. 问题描述 某个时间点,接收到接口响应慢报警. 过一会收到服务器cpu可用率低(<10%)报 ...
最新文章
- Java多线程模式-Balking模式
- PyTorch分布式训练
- java元婴期(19)----java进阶(spring(3)----AOP相关概念实现方式)
- faster-rcnn中添加Mask中的RoiAlign层,使回归框更精确( roi_align_layer.cu:240] Check failed: error == cudaSuccess *)
- 操作 Wave 文件(14): waveOutSetPlaybackRate、waveOutSetPitch
- 分布式锁之Redis6+Lua脚本实现原生分布式锁
- 【英语学习】【Daily English】U02 Daily Routine L02 I go to the gym every other day
- UDP报文观测以及DNS的工作原理
- MongoDB的Go语言驱动----mgo的使用指南
- 全屏 虚拟机_不用虚拟机直接在线用的 Linux,统统都在这里!
- python切割音频文件_python3使用pydub切分音频文件
- GNSS最终、快速、超快速星历下载地址汇总
- fanuc换刀宏程序详解_FANUC宏程序使用举例
- 面向对象:珍视你的好,一生温柔以待!
- 《古诗词里的快意人生》读后感
- 2022年5月网络教育大学英语B统考题库复习题及考试时间
- 一个实用的实时毛发渲染及着色方法
- 杜笙除镍树脂Tulsimer CH-90实际运用案例
- 基于百度AL平台人体检测实现人体关键点检测代码
- 胡子哥 观察日记 2020年10月5日(周一)