Java

maxLifetime导致fullgc stw耗时长

2021-04-25  本文已影响0人  holysu

背景

核心服务、并发较高,查询接接口最高几万qps 对停顿比较敏感

jvm

分库分表,对应多个数据库连接池对象

问题发现

stw告警,full gc stw超过500ms

查看jvm gc曲线图,old space一直慢慢上升,有内存泄露的感觉,但是fullgc后能回收掉

gc日志发现 cms最后一个阶段 final remark 时候耗时较久(需要加上参数 -XX:+PrintReferenceGC 才能打印具体什么类型的引用)

dump heap 发现有大量 finalizer ,内部都是 pgconnection 数据库连接对象

如何解决

根因分析

其实maxLifetime 机制本身没什么问题

maxLifeTime = 7 小时,当它清理连接的时候,gc age肯定是超过15的老对象了,要进入老年代

假设连接多个数据库 n, db连接池 minimumIdle = m,那么每隔 maxLifetime 就会有 T = m * n * maxLifeTime 个连接进入老年代, 案例里 m=8 , n=35, maxLifeTime=7小时,fullgc 大概10天一次

那么full gc 的时候大概有 8 * 35 * (10天 * 24 /maxLifeTime) = 9600个连接对象在老年代 非常多

连接的库越多、连接池min个数设置越大、fullgc间隔时间越长(老年代空间越大),那么 cms final remark 暂停就越久; 如果数据库选用的mysql,最好保留maxLifeTime机制,合理设置minimumIdle ,同时 jvm 堆大小不能一味的往大了设置,太大会导致 ygc、fullgc耗时变长

上一篇 下一篇

猜你喜欢

热点阅读