Netty的ChannelPool导致内存泄漏的排查经历

背景

接到了线上机器的报警,登上服务器,发现是Java进程挂了,看日志报了OOM:

java.lang.OutOfMemoryError: Java heap space

问题描述

内存溢出,那当然是看dump文件了。这里推荐大家在产线机器上都加上JVM参数-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath={path}/{to}/{dump},这样,JVMOOM的时候,会自动做一个内存dump,相当于保存现场。
拿到dump文件,放到MAT里面分析,以下是部分截图:
dump1

不看不知道,一看吓一跳:有一个class(包括其reference)竟然占据了1.6G的内存!
这个类叫NettyHttpClientService,是工程里面用来提供异步Http服务的,其实就是对Netty做了一层包装。这个类上线已久,之前工作得很好没出什么问题。最近一次上线,也没有对这个类做什么改动,只是新增了一处调用它的地方。

需要进一步挖掘NettyHttpClientService这个类。

问题分析

继续分析内存占用情况,发现其大头是一个ConcurrentHashMap,里面的每个node都占用了10M-20M的空间,而这个Map里面,已经存在了135node
dump2

看来还得去代码里面寻找真相。找到源头,以下是简化版的代码:

public class NettyHttpClientServiceImpl implements NettyHttpClientService, DisposableBean {
   
    // channelPoolMap是一个InetSocketAddress与ChannelPool的映射关系
    private AbstractChannelPoolMap<InetSocketAddress, FixedChannelPool> channelPoolMap = new AbstractChannelPoolMap<InetSocketAddress, FixedChannelPool>() {
   
        // 构建新的大小为200的ChannelPool
        @Override
        protected FixedChannelPool newPool(InetSocketAddress key) {
   
            return new FixedChannelPool(bootstrap.remoteAddress(key), new NettyHttpPoolHandler(), 200);
        }
    };

    // NettyHttpClientService的入口,参数是请求体RequestEntity,成功回调successCallback,失败回调errorCallback
    @Override
    public Promise<SimpleResponse
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值