首页 > 其他分享 >某定时任务OOM排查

某定时任务OOM排查

时间:2024-10-11 22:33:31浏览次数:1  
标签:ahdm OOM ajlcAjbs List zbajAjlc 排查 ckfkxx Heap 定时

现场定时任务 OOM,堆转储文件 8 G,先打成 tar. gz,再压缩一次,才得以传输过来。

工具-MAT (MemoryAnalyzer)

MAT下载地址
当前启动需要 JDK 17: JDK 17 下载地址 好像也可以使用 JDK 8,有兴趣的可以自己研究下
如果 dump 出来的 hprof 文件过大,比如这个文件 8 G,需要改下 MemoryAnalyzer. ini 文件。

-vmargs
--add-exports=java. base/jdk. internal. org. objectweb. asm=ALL-UNNAMED
-Xmx 8192 m

List Objects

outgoing references: 当前对象包含的引用
incoming references: 引用当前对象的引用

Shallow Heap 和 Retained Heap

个人理解 Shallow Heap 就是当前对象,不包含它含有的引用的值大小
Retained Heap 就是包含了自己及引用的大小,默认显示单位为 byte. 可以在 window->preference->Memory Analyzer -> Bytes Display 选项,选择 Smart, 可智能显示 KB, MB, GB。

Histogram 直方图

展示每个 class 实例的数量

Dominator Tree 支配树

展示存活的大对象

分析

查看 Leak Suspects

发现 arterySchedule_Worker-7 和 arterySchedule_Worker-6 都在 zbajZbckfkbService.batchUpdateZbajZbckfkb(zbajZbckfkb) 这一行。

image.png
image.png

查看支配树,确定大对象

image.png

RingBuffer 这个不知道干啥的,先忽略

arterySchedule_Worker-7 1.73 G 占 22.31%

在支配树这一条目执行 Show Retained Set 可以看到
zbajZbckfkb: 794673 个实例
ZbajAjlc : 176984 个实例

image.png

arterySchedule_Worker-6 1.22 G 占 15.75%

最大头的 3.2 G 到底是啥?

image.png

我先在 dominator_tree 最大的对象 Show Retained Set ,
image.png

然后在 char 上我执行 List Objects->with incoming references 来查看到底是哪些占了这么大空间,然后进行排序,发现有很多长得很像的对象,占用 14.61 MB,然后在 Retained Heap 这一列输入 1 MB.. 16 MB 进行过滤,发现总共有 226 个,结果占用 14.61*226/1024=3.2G

image.png
那就看看这 sql 在干嘛吧

image.png
结果发现,这些 sql 基本都是 SELECT c_ahdm,n_yckcs FROM db_zbaj.t_zdzck_hzb\u000a WHERE c_ahdm in (xxx),结果发现在循环调用的方法 buildAjlcData 中有
Map<String, Object> tccsMap = zbajAjlcService.getTccs (ajlcAjbs);

根据已有信息分析代码

private void getUpdateAjckAndAjlc() {
    //查控反馈信息
    List<ZbajAjck> ajckCkfk = zbajAjckService.getCkfkAndAjck();
    Map<String, Object> tmpCkfk = new HashMap<>();
    List<String> ahdm = new ArrayList<>();
    Set<String> ajlcAjbs = new HashSet<>();
  //.....
    if (CollectionUtils.isNotEmpty(ahdm)) {
        //获取要更新的案件流程表
        List<ZbajAjlc> zdzckAjlc = zbajAjlcService.selectAjlcByAhdm(ajlcAjbs);
        //获取要更新的查控反馈表
        Set<ZbajZbckfkb> zbajZbckfkb = zbajZbckfkbService.getZbajZbckfkbByAjbsL(ahdm);
        List<String> ajckbhL = new ArrayList<>();
        for (ZbajZbckfkb ckfkxx : zbajZbckfkb) {
        		// ...
                buildAjlcData(ajlcAjbs, zdzckAjlc, ckfkxx);  
        }    
    }

}
private void buildAjlcData(Set<String> ajlcAjbs, List<ZbajAjlc> zdzckAjlc, ZbajZbckfkb ckfkxx) {
    Map<String, Object> tccsMap = zbajAjlcService.getTccs(ajlcAjbs);
    for (ZbajAjlc zbajAjlc : zdzckAjlc) {
        String ajbs = zbajAjlc.getAjbs();
        if (tccsMap.containsKey(ajbs)) {//设置统查次数
            Integer tccs = (Integer) tccsMap.get(ajbs);
            zbajAjlc.setCccxcs(tccs == null ? 0 : tccs);
        }
        if (zbajAjlc.getAjbs().equals(ckfkxx.getAjbs())) {
            BigDecimal oldCcje = zbajAjlc.getZdzcczje();
            BigDecimal newCcje = ckfkxx.getCcje();
            zbajAjlc.setZdzcczje(zbajAjlc.getZdzcczje() == null ? ckfkxx.getCcje() : newCcje.add(oldCcje));
        }
        zbajAjlc.setZhyccccxywcc(Consts.SFYCC_YCC);//最后一次统查有无财产  1.有;2.无;
        zbajAjlc.setZxtcwcccs(Consts.WCC_ONE);//只要财产就将其清空
        zbajAjlc.setZdztcycc(1);//总对总统查有财产
    }
}
  • zbajZbckfkb 有 79 万个实例,执行 79 万次 buildAjlcData,但 ajlcAjbs 是固定的,所以tccsMap 没必要,可以把它提出循环外,由 79 万次-》1 次。
  • buildAjlcData 里的 zdzckAjlc循环,会执行 17 万次。外层 79 万 * 内层 17 万=1600 亿次。分析发现跟 ckfkxx 有关的就是设置某个金额,因此把该方法拿出循环。由 1600 亿次循环-》17 万次。
  • RecordEvent 显示是 artery-monitor 里的代码,由于没有在使用,因此将开关设置为关闭

关于其他的

为什么会有两个线程在执行这一个定义任务?
artery 的调度,不管前面是否有任务在执行,仍然会开启新任务。现在已经改成有任务未执行完,跳过后续要执行的调度。
如有不正确之处,欢迎指出。

标签:ahdm,OOM,ajlcAjbs,List,zbajAjlc,排查,ckfkxx,Heap,定时
From: https://www.cnblogs.com/studentytj/p/18459495

相关文章

  • 【STM32开发之寄存器版】(八)-定时器的编码器接口模式
    一、前言1.1编码器接口原理编码器模式主要用于检测旋转编码器的转动方向和转动速度。旋转编码器一般输出两路相位相差90度的脉冲信号(称为A相和B相),通过这两路信号,定时器可以判断编码器的旋转方向,并计数转动的脉冲数。1.2本次DEMO目标本次DEMO将使用STM32F103ZET6的PA6(......
  • 排查sshfs挂载失败的问题
    排查sshfs挂载失败的问题写代码在Linux上运行,但是熟悉的IDE(比如VScode)在自己的电脑上,可以使用sshfs把linux上的目录挂载到本地,再用VScode打开即可,可以使用下面的命令:sshfs-odebug,sshfs_debug,loglevel=debug-orw,allow_other,uid=1190,gid=1190,reconnect,ServerAliveInte......
  • 雾霾下雨天气户外人像街景拍摄Lr后期调色,手机滤镜PS+Lightroom预设下载!
    调色详情在雾霾下雨天气下拍摄的户外人像街景往往具有一种独特的氛围。通过Lightroom进行后期调色,可以进一步强化这种氛围,使照片更加富有情感和艺术感。预设信息调色风格:灰调风格预设适合类型:人像,雾霾,雨天,户外,街景等预设格式:XMP+DNG手机滤镜资源编号:00776支持软件:Lightro......
  • QT定时器+事件捕获
    QT定时器类定时器类的使用主要包括定时和启动两个步骤。要使用OTimer类,需要引用头文件:#include<QTimer>QTimer类常用的成员函数有(1)voidstart(std::chrono::milisecondsmsec):启动定时器,参数为定时时间(单位为毫秒),如:        QTimermyTimer;        ......
  • 富士胶片人像汽车照片Lr调色教程,手机滤镜PS+Lightroom预设下载!
    调色介绍富士胶片人像汽车照片的调色旨在营造出独特的复古、文艺氛围。通过Lightroom的调色工具,将人像与汽车完美融合在具有富士胶片特色的画面中,展现出别样的美感。预设信息调色风格:富士胶片风格预设适合类型:人像,街拍,自拍,模特照,封面照,汽车等预设格式:XMP+DNG手机滤镜资源......
  • 电影风格城市建筑地铁街拍摄影Lr调色教程,手机滤镜PS+Lightroom预设下载!
    调色介绍电影风格城市建筑地铁街拍摄影的Lr调色,旨在将城市建筑与地铁场景的街拍照片打造出具有电影质感的视觉效果,展现出都市的独特魅力与故事感。预设信息调色风格:电影风格预设适合类型:人像,地铁,街拍,自拍,公交车,火车,建筑等预设格式:XMP+DNG手机滤镜资源编号:00767支持软件:Li......
  • 【WCH蓝牙系列芯片】-基于CH582开发板—利用定时器加DMA方式模拟串口输出
    ------------------------------------------------------------------------------------------------------------------------------------在使用CH582芯片开发测试中,有个实际的用途是利用串口输出日志的方式,来进行程序的调试。CH582芯片一共提供了4组全双工的异步串口......
  • mysql占用内存过大问题排查
    如果MySQL占用内存过高,可以按照以下步骤进行排查:一、检查MySQL配置参数查看 innodb_buffer_pool_size:这个参数决定了InnoDB存储引擎缓冲池的大小,它会占用大量内存。如果设置得过大,可能导致内存占用过高。可以通过查询 SHOWVARIABLESLIKE'innodb_buffer_pool_size......
  • JAVA基础:FutureTasck 和 Callable、Timer定时任务
    1FutureTasck和Callable是JDK1.5之后,在JUC工具包提供了一个多线程工具类在多线程应用中,a线程可以通过FutureTask和Callable了解b线程是否执行完毕以及b线程执行的结果。可以实现两个线程之间的通信。自定义线程类,实现Callable接口,重写call方法,该方法执行的功能就是......
  • 频繁full gc 如何排查
    频繁fullgc通常表明应用程序在内存管理方面存在问题,可能导致性能下降,下面是排查步骤和一个详细的示例排查步骤收集GC日志首先,需要开启详细的GC日志,在JVM参数中添加-XX:+PrintGCDetails-XX:+PrintGCDateStamps-Xloggc:/path/to/gc.log分析GC日志使用工具GCViewer......