线上FullGC频繁的排查

简介: 线上FullGC频繁的排查:前段时间发现线上的一个dubbo服务Full GC比较频繁,大约每两天就会执行一次Full GC。

线上FullGC频繁的排查

问题

前段时间发现线上的一个dubbo服务Full GC比较频繁,大约每两天就会执行一次Full GC。

Full GC的原因

我们知道Full GC的触发条件大致情况有以下几种情况:

  1. 程序执行了System.gc() //建议jvm执行fullgc,并不一定会执行
  2. 执行了jmap -histo:live pid命令 //这个会立即触发fullgc
  3. 在执行minor gc的时候进行的一系列检查
执行Minor GC的时候,JVM会检查老年代中最大连续可用空间是否大于了当前新生代所有对象的总大小。
如果大于,则直接执行Minor GC(这个时候执行是没有风险的)。
如果小于了,JVM会检查是否开启了空间分配担保机制,如果没有开启则直接改为执行Full GC。
如果开启了,则JVM会检查老年代中最大连续可用空间是否大于了历次晋升到老年代中的平均大小,如果小于则执行改为执行Full GC。
如果大于则会执行Minor GC,如果Minor GC执行失败则会执行Full GC
  1. 使用了大对象 //大对象会直接进入老年代
  2. 在程序中长期持有了对象的引用 //对象年龄达到指定阈值也会进入老年代

对于我们的情况,可以初步排除1,2两种情况,最有可能是4和5这两种情况。为了进一步排查原因,我们在线上开启了 -XX:+HeapDumpBeforeFullGC。

    注意:
    JVM在执行dump操作的时候是会发生stop the word事件的,也就是说此时所有的用户线程都会暂停运行。
    为了在此期间也能对外正常提供服务,建议采用分布式部署,并采用合适的负载均衡算法

JVM参数的设置:

线上这个dubbo服务是分布式部署,在其中一台机子上开启了 -XX:HeapDumpBeforeFullGC,总体JVM参数如下:

-Xmx2g 
-XX:+HeapDumpBeforeFullGC 
-XX:HeapDumpPath=. 
-Xloggc:gc.log 
-XX:+PrintGC 
-XX:+PrintGCDetails 
-XX:+PrintGCDateStamps 
-XX:+UseGCLogFileRotation 
-XX:NumberOfGCLogFiles=10 
-XX:GCLogFileSize=100m 
-XX:HeapDumpOnOutOfMemoryError 

Dump文件分析

dump下来的文件大约1.8g,用jvisualvm查看,发现用char[]类型的数据占用了41%内存,同时另外一个com.alibaba.druid.stat.JdbcSqlStat类型的数据占用了35%的内存,也就是说整个堆中几乎全是这两类数据。如下图:

a

查看char[]类型数据,发现几乎全是sql语句。

b

接下来查看char[]的引用情况:

c

找到了JdbcSqlStat类,在代码中查看这个类的代码,关键代码如下:

构造函数只有这一个
public JdbcSqlStat(String sql){
    this.sql = sql;
    this.id = DruidDriver.createSqlStatId();
}

查看这个函数的调用情况,找到com.alibaba.druid.stat.JdbcDataSourceStat#createSqlStat方法:

public JdbcSqlStat createSqlStat(String sql) {
    lock.writeLock().lock();
    try {
        JdbcSqlStat sqlStat = sqlStatMap.get(sql);
        if (sqlStat == null) {
            sqlStat = new JdbcSqlStat(sql);
            sqlStat.setDbType(this.dbType);
            sqlStat.setName(this.name);
            sqlStatMap.put(sql, sqlStat);
        }

        return sqlStat;
    } finally {
        lock.writeLock().unlock();
    }
}

这里用了一个map来存放所有的sql语句。

其实到这里也就知道什么原因造成了这个问题,因为我们使用的数据源是阿里巴巴的druid,这个druid提供了一个sql语句监控功能,同时我们也开启了这个功能。只需要在配置文件中把这个功能关掉应该就能消除这个问题,事实也的确如此,关掉这个功能后到目前为止线上没再触发FullGC

d

其他

如果用mat工具查看,建议把 "Keep unreachable objects" 勾上,否则mat会把堆中不可达的对象去除掉,这样我们的分析也许会变得没有意义。如下图:Window-->References 。另外jvisualvm对ool的支持不是很好,如果需要oql建议使用mat。

image

目录
相关文章
|
数据可视化 算法 数据挖掘
基于python的笔记本电脑购买意愿影响因素分析,包括情感分析和聚类分析
本文通过Python大数据技术对笔记本电脑评论数据进行情感分析和聚类分析,揭示了产品性能、外观设计和用户地区等因素对购买意愿的重要影响,并为企业提供了优化产品设计和销售策略的参考。
745 2
|
8月前
|
人工智能 NoSQL Java
你的 AI Agent 为什么总是“失忆”?揭秘 Spring AI 中的记忆管理陷阱与破局之道
Spring AI Agent常“失忆”?根源在于:1)HTTP无状态导致上下文丢失;2)未显式配置ConversationMemory;3)工具结果未回写记忆。本文剖析三大原因,提供Redis分布式记忆、sessionId绑定、工具结果自动注入等实战方案,并介绍滑动窗口、摘要压缩等高级技巧,助你打造真正连贯、可信的智能体。(239字)
1049 2
|
9月前
|
人工智能 自然语言处理 算法
2025年AI 搜索优化(GEO)行业年度盘点:从资本爆发到入场公司初步分化
2025年,AI搜索优化(GEO)爆发式增长,取代传统SEO成营销新焦点。受全球资本热捧,中国市场规模突破480亿元,即搜AI与边鱼科技领跑,分别布局全域搜索与中小微企业服务。技术与商业闭环加速构建,行业迈向可持续价值竞争。
|
11月前
|
人工智能 Java Linux
Python高效实现Excel转PDF:无Office依赖的轻量化方案
本文介绍无Office依赖的Python方案,利用Spire.XLS、python-office、Aspose.Cells等库实现Excel与PDF高效互转。支持跨平台部署、批量处理、格式精准控制,适用于服务器环境及自动化办公场景,提升转换效率与系统稳定性。
1098 7
|
负载均衡 架构师 Cloud Native
阿里面试:服务与发现 ,该选 CP 还是 AP?为什么?
阿里面试:服务与发现 ,该选 CP 还是 AP?为什么?
阿里面试:服务与发现 ,该选  CP 还是 AP?为什么?
阿里面试:每天新增100w订单,如何的分库分表?这份答案让我当场拿了offer
例如,在一个有 10 个节点的系统中,增加一个新节点,只会影响到该新节点在哈希环上相邻的部分数据,其他大部分数据仍然可以保持在原节点,大大减少了数据迁移的工作量和对系统的影响。狠狠卷,实现 “offer自由” 很容易的, 前段时间一个武汉的跟着尼恩卷了2年的小伙伴, 在极度严寒/痛苦被裁的环境下, offer拿到手软, 实现真正的 “offer自由”。在 3 - 5 年的中期阶段,随着业务的稳定发展和市场份额的进一步扩大,订单数据的增长速度可能会有所放缓,但仍然会保持在每年 20% - 30% 的水平。
阿里面试:每天新增100w订单,如何的分库分表?这份答案让我当场拿了offer
|
存储 算法 架构师
阿里面试:PS+PO、CMS、G1、ZGC区别在哪?什么是卡表、记忆集、联合表?问懵了,尼恩来一个 图解+秒懂+史上最全的答案
阿里面试:PS+PO、CMS、G1、ZGC区别在哪?什么是卡表、记忆集、联合表?问懵了,尼恩来一个 图解+秒懂+史上最全的答案
|
存储 安全 Java
ConcurrentHashMap是如何保证线程安全的?
ConcurrentHashMap相当于是HashMap的多线程版本,它的功能本质上和HashMap没什么区别。因为HashMap在并发操作的时候会出现各种问题,比如死循环问题、数据覆盖等问题。而这些问题,只要使用ConcurrentHashMap就可以完美地解决。那问题来到了,ConcurrentHashMap它是如何保证线程安全的呢?
510 0
|
缓存 Java
java使用MAT进行内存分析
java使用MAT进行内存分析
|
Java 应用服务中间件 Maven
SpringBoot引入第三方jar包或本地jar包的处理方式
SpringBoot引入第三方jar包或本地jar包的处理方式
5823 1

热门文章

最新文章