欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

netty 使用 ChunkedWriteHandler 发送 TextWebSocketFrame 消息会导致内存溢出

最编程 2024-04-03 06:58:51
...

netty版本

		<dependency>
               <groupId>io.netty</groupId>
               <artifactId>netty-all</artifactId>
               <version>4.1.50.Final</version>
        </dependency>

此版本ChunkedWriteHandler 的write方法如下

public class ChunkedWriteHandler extends ChannelDuplexHandler {
	private final Queue<PendingWrite> queue = new ArrayDeque<PendingWrite>();
	
	@Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        queue.add(new PendingWrite(msg, promise));
    }
}

源码可知所有的消息都会被放置queue队列中,同时也不会触发channel高低水位设置,在大量消息堆积时导致内存无法回收OOM。堆内存分析如下:
在这里插入图片描述
解决:升级netty版本!

		<dependency>
               <groupId>io.netty</groupId>
               <artifactId>netty-all</artifactId>
               <version>4.1.108.Final</version>
        </dependency>

高版本对write方法进行了优化:

public class ChunkedWriteHandler extends ChannelDuplexHandler {
	private final Queue<PendingWrite> queue = new ArrayDeque<PendingWrite>();
	
	@Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        if (this.queueIsEmpty() && !(msg instanceof ChunkedInput)) {
            ctx.write(msg, promise);
        } else {
            this.allocateQueue();
            this.queue.add(new ChunkedWriteHandler.PendingWrite(msg, promise));
        }
    }
}

在加入queue前对消息类型进行了判断,因此TextWebSocketFrame消息将不会进入队列!

推荐阅读