首页 > 其他分享 >CGLIB动态代理对象GC问题排查

CGLIB动态代理对象GC问题排查

时间:2023-08-01 14:14:01浏览次数:51  
标签:Finalizer 对象 cpu 排查 线程 CGLIB GC ID

一、问题是怎么发现的

最近有个新系统开发完成后要上线,由于系统调用量很大,所以先对核心接口进行了一次压力测试,由于核心接口中基本上只有纯内存运算,所以预估核心接口的压测QPS能够达到上千。

压测容器配置:4C8G

先从10个并发开始进行发压,结果cpu一下就飙升到了100%,但是核心接口的qps才200左右。于是观察jvm的垃圾回收发现younggc很频繁,但是fullGC数量为零。

二、排查问题的详细过程

由于刚一开始压测,容器cpu就飙升到了100%,所以需要先定位cpu使用率问题,找出使用cpu最高的几个进程。可以通过top命令查找进程ID,发现正是压测的Java应用进程ID;然后在定位该金晨曦cpu使用率最高的线程,可以通过top -p 进程ID -H 命令显示该进程下的线程使用cpu信息。

top

top -p 进程ID -H

图片中PID列则为十进制显示的线程ID,然后转换为16进制;在通过jstack 系统进程ID | grep 16进制线程ID 命令找到对应的线程信息如下,也就是该线程占用了一半左右的cpu。

jstack 系统进程ID | grep 16进制线程ID

此时定位到了Finalizer线程,但是这个线程又有什么作用呢?

原来这个线程会不停的循环等待java.lang.ref.Finalizer.ReferenceQueue中的新增对象。一旦Finalizer线程发现队列中出现了新的对象,它会弹出该对象,调用它的finalize()方法,将该引用从Finalizer类中移除,因此下次GC再执行的时候,这个Finalizer实例以及它引用的那个对象就可以被垃圾回收掉了。如果这个线程一直在不停的工作,说明Finalizer的队列中有许多等待GC的垃圾对象。此时可以通过另一个命令来查看等待回收的垃圾对象有哪些。

jmap -finalizerinfo 进程ID

Count Class description
-------------------------------------------------------
32221 com.jd.price.deep.exact.entity.coupons.DeepExactCouponVo$$EnhancerByCGLIB$$200e6ee6
14908 com.jd.pricedoor.compute.promotion.MultiplePromotion$$EnhancerByCGLIB$$a59933de
11982 java.util.zip.Deflater
1 java.net.SocksSocketImpl

通过上述结果可以发现有好多的业务对象,通过类名可以看到这些对象都是通过CGLIB动态代理创建的,而且这些动态代理类都默认实现了finalize方法,导致这些对象在进行垃圾回收时必须先要执行finalize方法,所以都积压到了finalizer的队列中。

三、如何解决问题

通过上述排查过程发现,是由于大量的业务对象通过CGLIB创建了动态代理类,而这些代理都是系统处理请求时创建的临时对象,请求完成后,这些临时对象就需要被垃圾回收掉,从而导致Finalizer线程执行频繁抢占了cpu资源。

针对以上分析结果所以有了如下几种解决方案:

1.不要使用CGLIB来给那些需要频繁进行垃圾回收的对象创建动态代理,可以手动创建静态代理类。

2.对象复用,尽量减少临时对象的产生。

作者:京东零售 曹志飞

来源:京东云开发者社区

标签:Finalizer,对象,cpu,排查,线程,CGLIB,GC,ID
From: https://www.cnblogs.com/jingdongkeji/p/17596280.html

相关文章

  • pip install指定gcc g++版本的方法
    有时候安装某个包可能会遇到gcc版本过低的问题,但是系统上可能安装了好几个版本的gcc。那么一种很简单的解决办法如下:切换到gcc对应的路径,例如cd/usr/local/bin/gcc假如这个路径下有这么几个版本的gcc,g++:ls>>>gccgcc-7.3.0g++g++-7.3.0在pipinstall命令前......
  • SpringCloud Gateway 在微服务架构下的最佳实践
    作者:徐靖峰(岛风)前言本文整理自云原生技术实践营广州站Meetup的分享,其中的经验来自于我们团队开发的阿里云CSB2.0这款产品,其基于开源SpringCloudGateway开发,在完全兼容开源用法的前提下,做了诸多企业级的改造,涉及功能特性、稳定性、安全、性能等方面。为什么需要微服务网......
  • 【AGC】Publishing API调用问题汇总
    ​【问题背景】开发者可以通过PublishingAPI完成几乎所有应用的管理和发布工作,自己制定自动发布接口。PublishingAPI有很多接口,包括了查询应用信息、更新应用信息、上传文件、提交发布等主要接口。下面总结了一些开发者在使用PublishingAPI过程中容易遇到的问题,供大家在使用时......
  • P2257 YY的GCD
    传送门首先得到一个非常显然的柿子\[\sum_{p}\sum_{d}\lfloor\frac{n}{pd}\rfloor\lfloor\frac{m}{pd}\rfloor\]我们可以考虑T=pd,然后转化柿子\[\sum_{T}\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor\sum_{p|T}\mu(\frac{T}{p})\]后面这一块可以预处理。......
  • AGC063C Add Mod Operations
    感觉是非常纯的思维题。题意给两个长度为\(n\)的序列\(A,B\)。你可以对\(A\)做不超过\(n\)次操作,形如对于所有元素,先加上\(x\)再对\(y\)取模。其中\(0\lex<y\le10^{18}\)是由你决定的任意整数。给出一种方案将\(A\)变成\(B\),或声明无解。\(1\len\le200......
  • 服务器管理工具WGCLOUD如何实现单点登录SSO
    WGCLOUD是支持单点登录SSO的WGCLOUD从v3.4.8版本开始支持SSO单点登录,也就免密登录,只需要修改server的配置文件中的如下配置项即可,改为yes,然后重启server就生效了#是否开启免密登录,yes开启,no关闭,此功能开启需升级到专业版openSSO:no我们怎么实现免登录呢,请看如下这个链接,就是......
  • GCD
    GCD洛谷题目描述一张图有\(n\)个节点,编号为\(1,2,3,\dots,n\)。其中\(i\)号节点会向\(j\)号节点连一条边权为\(|i-j|\)的无向边,当且仅当\(\gcd(i,j)=i,\operatorname{lcm}(i,j)=j\)时连边。现询问\(q\)次,每次询问求\(x\)到\(y\)的最短路径。输入格式第一......
  • (转)关于施用full gc频繁的分析及解决
    分析当频繁fullgc时,jstack打印出堆栈信息如下:sudo-uadmin-H/opt/taobao/java/bin/jstack`pgrepjava`>#yourfilepath#可以看到的确是在跑低价信息另外在应用频繁fullgc时和应用正常时,也执行了如下2种命令:sudo-uadmin-H/opt/taobao/java/bin/jmap-histo`pgrep......
  • AGC049F 更优秀的做法
    题面给定长度为\(n\)的整数序列\(A\),\(B\)和\(C\)。snuke是开心的,当且仅当下面的条件满足:对于任意整数\(x\),均有\(\sum_{1\lei\len}|A_i-x|\le\sum_{1\lei\len}|B_i-x|\)。他决定改变\(A\)中的一些元素来变得开心。把\(A_i\)改成\(t\)需要花费......
  • hdu7319 String and GCD
    StringandGCD首先我们需要用kmp的fail建树,然后需要利用到欧拉反演。\[n=\sum_{d|n}\varphi(d)\]对于这题来说\[(i,j)=\sum_{d|(i,j)}\varphi(d)=\sum_{d|i,d|j}\varphi(d)\]那么我们只需要用一个桶存每个约数从根到当前节点出现了多少次。然后枚举约数也有一个技巧,具体......