问题描述
- 线上生产机器fullgc很频繁几乎一分钟一次,younggc确无。
问题分析
- fullgc频繁第一反应是大对象导致的,但是这次上线版本改动内容也只是微小改动,并没有大改动,不太可能产生大对象,而且younggc为空很不正常。
- 看异常日志的时候看到提示gc之前没有调用ByteBuf.release(netty默认泄露检测级别下,按照1%的比例来抽查,所以过了一会才打出这一条日志)。根据日志提示设置jvm参数-Dio.netty.leakDetection.level=advanced,该参数级别设置后会打印详细发生泄露的地方,排查之后发现每次调用时都使用直接内存分配,代码本质是想获取直接内存引用的。
- 这个接口调用很频繁,虽然每次直接内存分配不大,但很快就达到1个g,堆外内存在分配的时候,会有一个阈值,可以通过MaxDirectMemory参数设置,默认为Xmx减去一个suvivor大小。当快达到该阈值的时候,会调用一把System.gc主动触发一把fullgc,我们没有设置DisableExplictGC这个参数,所以System.gc是有效的。
- 查看线上堆外内存的使用与fullgc的回收发现节奏比较吻合。younggc没有是因为young区分配 的比较大,还没来得及回收就随着被fullgc掉了。
网友评论