Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >现网gc问题定位三板斧

现网gc问题定位三板斧

原创
作者头像
fynnliu
发布于 2018-10-12 08:33:58
发布于 2018-10-12 08:33:58
1.9K00
代码可运行
举报
文章被收录于专栏:后台经验后台经验
运行总次数:0
代码可运行

国庆假期临近,组里的小伙伴们都开开心心请假回家了,然后cgi很应景的出现了多台机器的频繁full gc,所以只能上阵用力撸一把了。

第一板斧:看gc日志。

首先登上机器,进入日志目录/usr/local/services/javacgi_qqke_web-2.0/log

javacgi_qqke_web这个工程是比较有节操的了,配置了输出gc日志。直接grep一下FULL GC,看下是不是和告警匹配。

用力敲下面的命令

grep -rn "Full GC" cgi_ke_web.gclog

观察下FULL GC的时间,明显太频繁了,而且老年代每次回收完都没什么变化,可以初步判断是内存泄漏了,有大量的内存回收不了

ps,如果遇到没有节操的工程,没有输出gc日志,不用怕,现场实时观察就好

用力敲下下面的命令,21332是pid,1000毫秒输出一次,输出10次。

/usr/local/services/jdk7_32-1.0/bin/jstat -gcutil 21332 1000 10

第二板斧:jmap看堆内存情况

/usr/local/services/jdk7_32-1.0/bin/jmap -heap 21332

通过jmap工具,可以清楚看到,老年代耗尽了,但是永久带也不够接受老年代的数据,所以无论怎么回收,老年代不减少,导致了频繁 FULL GC

第三板斧:MAT

首先先用jmap工具把堆dump下来。

/usr/local/services/jdk7_32-1.0/bin/jmap -dump:live,format=b,file=dump.hprof 21332

把文件下载到本地机器,MAT是eclipse出品,windows使用正常,mac能不能用看造化

别忘了修改这个文件,调整MAT内存大小,不然装不下服务器的堆文件的

导入成功后,直接点内存泄漏分析

分析的结果告诉我们Sppclient中疑似内存泄漏。

仔细看一下内存分析,内存主要用在两个和后端spp-qun服务连接的qcon上面,每个qcon占用了300M+的内存,而且sppclient是全局单例,里面的数据都是不会回收的,这就是造成内存泄漏的主要来源。

看下这个队列里面的元素,有131672个。。

再去看下代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public boolean write(Object msg, ChannelFutureListener connectionListener, ChannelFutureListener writeListener) {
if (channels.size() < maxChannels) {
return doConnectAndWrite(msg, connectionListener, writeListener);
    } else {
        Object[] ca = channels.toArray();
        int size = ca.length;
        nextChannel = (nextChannel + 1) % size;
        Channel c = (Channel) ca[nextChannel];
        if (c.isConnected()) {
            c.write(msg).addListener(writeListener);
        } else {
            ChannelFuture connFuture = ch2connFuture.get(c);
            if (connFuture != null) {
                connFuture.addListener(connectionListener);
            } else {
log.error("no connection future!!! channel={}", c);
            }
        }
return true;
    }

}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private boolean doConnectAndWrite(final Object msg, ChannelFutureListener connectionListener, final ChannelFutureListener writeListener) {

//新建tcp连接
    MonitorUtils.monitor(3222607);

    ChannelFuture future = bootstrap.connect(addr);
    Channel channel = future.getChannel();
    future.addListener(connectionListener);
    ch2connFuture.put(channel, future);
    //这里注意,这个channel可能还未连接成功
    channels.add(channel);
    return true;
}

看完代码,更怀疑人生了,理论上ch2connFuture 和 channels 数量应该是一致的,而且这个队列设置了上限65535,为啥现网会超出这么多。。

这时我们再回去看下MAT中的数据,channels只有17个。。

为啥?!!直到看完了add的实现,才终于恍然大悟

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Override
public boolean add(Channel channel) {
    ConcurrentMap<Integer, Channel> map =
        channel instanceof ServerChannel? serverChannels : nonServerChannels;

    boolean added = map.putIfAbsent(channel.getId(), channel) == null;
    if (added) {
        channel.getCloseFuture().addListener(remover);
    }
return added;
}

关键就在于add的操作判断了channel里面是否已经有了即将添加的channel,而这个判断条件是对比channel的id,那么问题来了,这里的channel其实是一个异步初始化的future类型,在执行add操作的时候,并不能保证拿到id,所以这里会出现大量id为0的channel。。而只要和后端建立连接的时候出现网络问题,这里的bug就会触发,就会导致内存泄漏。

总结下,这次的full gc是因为网络抖动导致的spp-qun调用的框架bug在现网出现,最快的解决方法就是重启服务。。。。

小事重启果然是在哪里都适用的操作啊。。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
从一次线上故障思考Java问题定位思路
CGI 服务发布到现网后,现网机器出现了Full GC告警,同时CPU飙高99%。在优先恢复现网服务正常后,开始着手定位Full GC的问题。
Tencent JCoder
2018/09/23
1.7K0
从一次线上故障思考Java问题定位思路
【日活百万电商返利App】一次线上JVM问题定位排查
查看进程使用gc情况: jstat -gc 16969<pid> 5000(打印时间间隔)
用户2032165
2020/03/27
9600
【日活百万电商返利App】一次线上JVM问题定位排查
记录线上服务频繁full gc问题排查
线上服务GC问题,是JAVAJAVA程序比较典型的问题,也是非常考验工程师的排查能力。能真正排查定位的人不多,要么原理没吃透、要么没有实战经验,看到此问题无从下手。
姆斯java实战分享
2023/07/23
1.4K0
GC原理介绍、排查FGC及线上故障的步骤
JAVA堆分为新生代(Young Generation)和老年代(Old Generation)( 也就是图中对应的New Generation 和 tenured Generation)用于存储对象实例。
chenchenchen
2022/03/09
4.6K0
GC原理介绍、排查FGC及线上故障的步骤
从一次线上故障思考Java问题定位思路
CGI 服务发布到现网后,现网机器出现了Full GC告警,同时CPU飙高99%。在优先恢复现网服务正常后,开始着手定位Full GC的问题。在现场只能够抓到四个GC线程占用了很高的CPU,无法抓到引发Full GC的线程。查看了服务故障期间的错误日志,发现更多的是由于Full GC引起的问题服务异常日志,无法确定Full GC的根源。为了查找问题的根源,只能从发布本身入手去查问题,发现一次bugfix的提交,有可能触发一个死循环逻辑:
Tencent JCoder
2018/10/09
9350
从一次线上故障思考Java问题定位思路
[三步法] 可视化分析定位线上 JVM 问题
前提是线上 JVM 配置了以下参数: [题外话:JDK 版本 1.6,现在大部分互联网企业应用系统应该是 1.8 以上了吧 ]
IT技术小咖
2020/04/02
3.1K0
[三步法] 可视化分析定位线上 JVM 问题
记一次不太成功的频繁 full gc 排查过程
选取了上周优化前后的两个典型工作日上午9:00到晚上9:00的GC情况。优化前一天要发生高达上10次的full gc,young gc也非常频繁。优化后的图已经没有出现full gc,young gc的频率也大大降低了,所以说基本完成目标。
程序员小猿
2021/01/19
1.5K0
JVM实战—10.MAT的使用和JVM优化总结
2.百万级数据误处理导致频繁FGC(大数据量加载到内存处理 + String.split())
东阳马生架构
2025/03/19
1190
2020-12-28:java中,生产环境服务器变慢,如何诊断处理?
使用 top 指令,服务器中 CPU 和 内存的使用情况,-H 可以按 CPU 使用率降序,-M 内存使用率降序。排除其他进程占用过高的硬件资源,对 Java 服务造成影响。
福大大架构师每日一题
2020/12/28
1.7K0
如何对GC算法进行调优呢?
对GC(Garbage Collection,垃圾收集)算法进行调优是一个涉及多个方面的复杂任务。
小冷coding
2024/04/26
2060
如何对GC算法进行调优呢?
Java垃圾回收机制深度剖析:大对象定位与问题解决的终极秘籍!
在Java开发的浩瀚宇宙中,垃圾回收机制宛如一颗璀璨的星辰,它默默守护着程序的内存健康,却常常被开发者忽视。今天,就让我们一起深入探索Java垃圾回收机制的奥秘,掌握定位大对象与问题的绝技,让你的代码在性能的赛道上一骑绝尘!如果你觉得这篇文章对你有帮助,别忘了点赞和评论哦,让我们一起互动起来!
疯狂的KK
2025/01/17
1930
Java垃圾回收机制深度剖析:大对象定位与问题解决的终极秘籍!
万字长文 JVM调优之垃圾回收机制深度剖析:大对象定位与问题解决的终极秘籍
在Java开发的浩瀚宇宙中,垃圾回收机制宛如一颗璀璨的星辰,它默默守护着程序的内存健康,却常常被开发者忽视。今天,就让我们一起深入探索Java垃圾回收机制的奥秘,掌握定位大对象与问题的绝技,让你的代码在性能的赛道上一骑绝尘!如果你觉得这篇文章对你有帮助,别忘了点赞和评论哦,让我们一起互动起来!
疯狂的KK
2025/01/17
2510
万字长文  JVM调优之垃圾回收机制深度剖析:大对象定位与问题解决的终极秘籍
Java内存问题分析与定位
一般建议 parallel scavenge (JDK8默认GC),适用大部分场景。
Vincent-yuan
2022/05/06
8540
Java内存问题分析与定位
JVM 监控 1
服务监控是一个服务中非常重要的组成部分,直接决定了问题的发现及排查速度,并且从一定程度上提高服务一个周期内的可用性。在Java服务中,除了对于 业务、接口耗时&性能的监控之外还需要对Java 所依赖的JVM进行一定的监控策略。对于JVM的合理监控可以帮助我们更加全面的发现问题:比如说内部接口耗时忽然上升、oom频出这类问题,并且合理的JVM监控及分析策略,能够以此为依据进行服务所使用JVM的调优,从而提升稳定性及性能。
邹志全
2020/02/25
7300
JVM 监控 1
线上服务的FGC问题排查,看这篇就够了!
整个案例的分析过程中,其实涉及到很多GC的原理知识,如果不懂得这些原理就着手处理,其实整个排查过程是很抓瞎的。
码农架构
2020/11/09
1.9K0
线上服务的FGC问题排查,看这篇就够了!
MAT工具定位分析Java堆内存泄漏问题方法
MAT,全称Memory Analysis Tools,是一款分析Java堆内存的工具,可以快速定位到堆内泄漏问题。该工具提供了两种使用方式,一种是插件版,可以安装到Eclipse使用,另一种是独立版,可以直接解压使用。
朱季谦
2021/06/29
3.1K0
Metaspace内存不足导致FGC问题排查
清楚的记得是2020/7/25 14:34分左右,周六的下午,我还在公司苦逼的加班中,突然钉钉告警群里出现大量应用OP的dubbo超时调用、空指针异常,异常中间还有Metaspace元空间不足等异常:
LiosWong
2020/09/01
3.8K0
Metaspace内存不足导致FGC问题排查
Java性能诊断与调优工具:如何使用 JDK 自带工具(jstat、jmap、jvisualvm)进行性能分析?
本文将详细解析 JDK 自带的性能分析工具,结合实际案例展示如何利用 jstat、jmap 和 jvisualvm 分析内存、线程和 GC 性能问题,并提出优化策略。
猫头虎
2024/12/24
4990
JVM第一篇:一个Java内存泄漏的排查案例
最近在看《深入理解Java虚拟机:JVM高级特性与最佳实践》(第二版)这本书,理论+实践结合,深入浅出,强烈推荐给大家。 这两天在“小怪的java群”里面也对JVM内容进行了一个讨论,讨论的内容主要包括如下几个方面: 1)内存溢出和内存泄露的介绍? 2)如何排查和处理内存泄露? 一、内存溢出和内存泄露 一种通俗的说法。 1、内存溢出:你申请了10个字节的空间,但是你在这个空间写入11或以上字节的数据,出现溢出。 2、内存泄漏:你用new申请了一块内存,后来很长时间都不再使用了(按理应该释放),但是
黄小怪
2018/06/06
8.5K0
JVM
重学Java系列之深入理解JVM虚拟机6:JNDI,OSGI,Tomcat类加载器实现
hhss
2021/02/12
6680
JVM
推荐阅读
相关推荐
从一次线上故障思考Java问题定位思路
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验