full gc老年代反倒增加直到填满?

问题现象:full gc(System.gc())不能有效回收老年代空间,每次full gc仅能回收几十KB甚至不回收反而增长若干MB,比较相邻两次1小时定时full gc发现一小时内老年代空间并无太大增长,反倒是在full gc执行的1秒内上涨,最大可达100+MB/h,直到老年代填满

系统配置:JVM 8g (年轻代3g,老年代5g),幸存者区8轮存活晋升老年代,使用CMS收集器,工程为普通java工程,配置1200最大并发的线程池处理请求流量

目前收集到的信息:通过分析dump发现有大量的byte[] char[] String,以及ThreadLocal$ThreadLocalMap$Entry,经检查线程出口已经调用ThreadContext.clearAll()但并无问题,未发现我方代码内存泄漏点,log4j内置对象较多,但优化log4j配置后只能延缓老年代空间填满速度,并不能从根本解决问题,且完全一致的代码并不能在其它环境复现问题

1.如果题主怀疑是 log4j 导致的内存泄露,可以换成 logbak 试试

2.如果题主分析dump文件的工具是 VisualVM的话,可以对比分析 JVM 在Full GC前后的两个 dump 文件,看下类在内存中占比的变化,从而定位到泄漏的具体原因

(1)

(2) 

 -XX:+HeapDumpBeforeFullGC 实现在Full GC前dump

 -XX:+HeapDumpAfterFullGC 实现在Full GC后dump