Netty 直接内存溢出问题

  • 日志分析

Netty 内存溢出,但无详细到具体溢出位置

 

  •  添加显示级别,定位到具体报错位置

 

 

  • 监控直接内存使用情况,可以使用如下代码,在启动时加载(通过反射获取到直接内存使用情况)
package netty.util;

import java.lang.reflect.Field;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils;

import io.netty.util.internal.PlatformDependent;
/*直接内存监控*/
public class DirectMemoryReporter {
    private static final Logger LOGGER = LoggerFactory.getLogger(DirectMemoryReporter.class);

    private static final int _1K = 1024;

    private static final String BUSINESS_KEY = "netty_direct_memory";

    private AtomicLong directMemory;

    public void init() {
        Field field = ReflectionUtils.findField(PlatformDependent.class, "DIRECT_MEMORY_COUNTER");
        field.setAccessible(true);
        try {
            directMemory = ((AtomicLong) field.get(PlatformDependent.class));
            startReport();
        } catch (IllegalAccessException e) {
            LOGGER.error("netty_direct_memory error", e);
        }
    }

    public void startReport() {

        Runnable runnable = () -> {
            doReport();
        };
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
        // 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间
        service.scheduleAtFixedRate(runnable, 30, 1, TimeUnit.SECONDS);
    }

    private void doReport() {
        try {
            int memoryInKB = (int) (directMemory.get());
            LOGGER.info("{}:{}KB", BUSINESS_KEY, memoryInKB/1024);
        } catch (Exception e) {
            LOGGER.error("netty_direct_memory error", e);
        }
    }
}
  •  idea 配置直接内存大小 方便测试

 

 

 

 

  • 最终定位问题代码如下:添加了release后解决问题

使用 ByteBuf.readBytes 读取一定的字节数ByteBuf对象,如果长时间接收数据,就会导致内存溢出
// 读取包头  4个字节(此方法会产生新的ByteBuf,需要手动释放堆外内存;或者使用readBytes(byte[]))
ByteBuf da = in.readBytes(4);
da.release();

查看源码,注意标红区域,有说明会创建一个新的buffer

 

posted @ 2022-11-09 20:20  isme_533  阅读(814)  评论(0)    收藏  举报