内存泄漏问题LEAK: ByteBuf.release() was not called before it‘s garbage-collected. See https://netty.io

背景

在这里插入图片描述

前端快速点击加减,反应迟缓
流程:前端->后端->plc
暗区改善后端需要给plc一次发送多次指令,但是日志显示

核心记忆

记住一点内存泄漏ChannelInboundHandlerAdapter 这个必须在读完释放掉bytebuf,具体如下代码所示,也就是添加ReferenceCountUtil.release(in);

chatgpt回答

即使您继承了 ChannelInboundHandlerAdapter,在您的自定义处理器中仍然需要负责释放 ByteBuf,以避免内存泄漏。当您继承了 SimpleChannelInboundHandler,Netty 会在处理完消息后自动释放 ByteBuf,因此您不需要手动调用 ReferenceCountUtil.release 来释放 ByteBuf。这是 SimpleChannelInboundHandler 的一个优点,它会自动帮助您管理资源,防止内存泄漏。

/**
 * WebServerHandler.java
 * Created at 2022-08-30
 * Copyright (C) 2022 WEGO Group, All rights reserved.
 */
package com.wg.server;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.ObjectUtil;
import com.wg.constant.Constants;
import com.wg.constant.HttpStatus;
import com.wg.util.MessageUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 

ClassName: WebServerHandler

*

Description: 主程序入口服务器消息处理器

* * @author chenyuxiang * @date 2022-08-30 */ @Slf4j @Controller @Tag(name = "确认连接") @ChannelHandler.Sharable public class WebServerHandler extends ChannelInboundHandlerAdapter { /** 接入的主程序入口服务 */ public static final Map MASTER_MAP = new ConcurrentHashMap<>(); @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { String uuid = ctx.channel().id().asLongText(); MASTER_MAP.put(uuid, ctx); log.info("连接请求进入: {}, 地址: {}", uuid, ctx.channel().remoteAddress()); super.channelActive(ctx); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { String uuid = ctx.channel().id().asLongText(); MASTER_MAP.remove(uuid); ctx.channel().close(); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { ByteBuf in = (ByteBuf) msg; try { byte[] bytes = new byte[Constants.MEG_LENGTH]; in.readBytes(bytes); log.info("收到消息 --> {}", HexUtil.encodeHexStr(bytes)); String msgId = HexUtil.encodeHexStr(new byte[]{bytes[Constants.MSG_ID_POS]}); //处理CountDownLatch if (ObjectUtil.isNotNull(MessageUtil.MSG_ID_COUNT_DOWN_LATCH.get(msgId))){ MessageUtil.MSG_ID_COUNT_DOWN_LATCH.get(msgId).countDown(); MessageUtil.MSG_ID_COUNT_DOWN_LATCH.remove(msgId); } } finally { // 释放ByteBuf ReferenceCountUtil.release(in); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { String uuid = ctx.channel().id().asLongText(); MASTER_MAP.remove(uuid); log.error(cause.getMessage()); ctx.close(); } }

你可能感兴趣的:(websocket,chatgpt)