[英]Memory issue in netty
我正在使用Netty 4.0.32。 我已經分配了MaxDirectMemorySize:256M
我的BootStrap是這樣的:
bootStrap = new ServerBootstrap();
childGroup = new NioEventLoopGroup();
bootStrap.localAddress(protocolConstant.getPort());
bootStrap.channel(NioServerSocketChannel.class);
bootStrap.group(PARENTGROUP, childGroup);
bootStrap.childHandler(new MailChannelInitializer());
bootStrap.option(ChannelOption.SO_BACKLOG, BACKLOG);
bootStrap.childOption(ChannelOption.AUTO_READ, true);
bootStrap.childOption(ChannelOption.MAX_MESSAGES_PER_READ, 1 * 1024);
bootStrap.childOption(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, 512);
bootStrap.childOption(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, 256);
bootStrap.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
我的管道如下所示:
SslHandler <-> ByteToMessageCodec(將ByteBuf轉換為byte [],反之亦然)<-> BusinessLogicHandler
1)用於sslsupport的SslHandler。 我正在使用Java的SslEngine。
2)我像這樣擴展ByteToMessageCodec:
private class ByteConversionCodec extends ByteToMessageCodec<byte[]> {
@Override
protected void encode(ChannelHandlerContext ctx, byte[] msg, ByteBuf out)
throws Exception {
if (!ctx.channel().isWritable()) {
ctx.flush();
}
out.writeBytes(msg);
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in,
List<Object> out) throws Exception {
byte[] arr;
if (in.hasArray()) {
arr = in.array();
}
else {
arr = new byte[in.readableBytes()];
in.readBytes(arr);
}
out.add(arr);
}
}
如果在調用編碼時通道不可寫,則添加刷新請求,以使通道再次可寫。 這個對嗎?
3)BusinessLogicHandler將處理指定給一個線程池,該線程池執行asyncprocessing(涉及IO)並使用SocketChannel對象寫回到管道。 所有寫操作均源自線程池。 最后,我在所有寫入之后添加了flush(),以便刷新所有未完成的寫入。 每個寫調用都涉及一個byte [],最大大小為300bytes。 所有寫入的總和總計約為20Mb。
Thread [nioEventLoopGroup-3-1] (Suspended)
Thread.sleep(long) line: not available [native method]
Bits.reserveMemory(long, int) line: 651
DirectByteBuffer.<init>(int) line: 123
ByteBuffer.allocateDirect(int) line: 306
PoolArena$DirectArena.newChunk(int, int, int, int) line: 645
PoolArena$DirectArena(PoolArena<T>).allocateNormal(PooledByteBuf<T>, int, int) line: 228
PoolArena$DirectArena(PoolArena<T>).allocate(PoolThreadCache, PooledByteBuf<T>, int) line: 212
PoolArena$DirectArena(PoolArena<T>).allocate(PoolThreadCache, int, int) line: 132
PooledByteBufAllocator.newDirectBuffer(int, int) line: 271
PooledByteBufAllocator(AbstractByteBufAllocator).directBuffer(int, int) line: 155
PooledByteBufAllocator(AbstractByteBufAllocator).directBuffer(int) line: 146
PooledByteBufAllocator(AbstractByteBufAllocator).buffer(int) line: 83
SslHandler.allocate(ChannelHandlerContext, int) line: 1504
SslHandler.allocateOutNetBuf(ChannelHandlerContext, int) line: 1514
SslHandler.wrap(ChannelHandlerContext, boolean) line: 517
SslHandler.flush(ChannelHandlerContext) line: 500
DefaultChannelHandlerContext(AbstractChannelHandlerContext).invokeFlush() line: 663
DefaultChannelHandlerContext(AbstractChannelHandlerContext).flush() line: 644
Server$MailChannelInitializer$ByteConversionCodec.encode(ChannelHandlerContext, byte[], ByteBuf) line: 134
Server$MailChannelInitializer$ByteConversionCodec.encode(ChannelHandlerContext, Object, ByteBuf) line: 1
ByteToMessageCodec$Encoder.encode(ChannelHandlerContext, I, ByteBuf) line: 168
ByteToMessageCodec$Encoder(MessageToByteEncoder<I>).write(ChannelHandlerContext, Object, ChannelPromise) line: 107
Server$MailChannelInitializer$ByteConversionCodec(ByteToMessageCodec<I>).write(ChannelHandlerContext, Object, ChannelPromise) line: 108
DefaultChannelHandlerContext(AbstractChannelHandlerContext).invokeWrite(Object, ChannelPromise) line: 633
AbstractChannelHandlerContext.access$1900(AbstractChannelHandlerContext, Object, ChannelPromise) line: 32
AbstractChannelHandlerContext$WriteTask(AbstractChannelHandlerContext$AbstractWriteTask).write(AbstractChannelHandlerContext, Object, ChannelPromise) line: 908
AbstractChannelHandlerContext$WriteTask(AbstractChannelHandlerContext$AbstractWriteTask).run() line: 893
NioEventLoop(SingleThreadEventExecutor).runAllTasks(long) line: 358
NioEventLoop.run() line: 357
SingleThreadEventExecutor$2.run() line: 112
DefaultThreadFactory$DefaultRunnableDecorator.run() line: 137
FastThreadLocalThread(Thread).run() line: 745
因此,我發現獲取內容存在延遲。 線程休眠一段時間以獲取內存。 有人能幫助我解決這種情況嗎? 謝謝。
如果在調用編碼時通道不可寫,則添加刷新請求,以使通道再次可寫。 這個對嗎?
在我看來,這不合適。 您的編碼器沒有嘗試寫入通道,而應該只是嘗試將byte[]
寫入ByteBuf
。 您的BusinessLogicHandler已經做出是否寫入以及是否刷新的決定。
您是否嘗試過刪除此代碼以查看它是否可以解決您的問題?
if (!ctx.channel().isWritable()) {
ctx.flush();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.