[英]Memory issue in netty
I am using Netty 4.0.32. 我正在使用Netty 4.0.32。 I have allocated MaxDirectMemorySize:256M
我已经分配了MaxDirectMemorySize:256M
My BootStrap is like this: 我的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);
My pipeline looks like this: 我的管道如下所示:
SslHandler <-> ByteToMessageCodec(tranforms the ByteBuf to byte[] and vice versa) <-> BusinessLogicHandler SslHandler <-> ByteToMessageCodec(将ByteBuf转换为byte [],反之亦然)<-> BusinessLogicHandler
1) SslHandler for sslsupport. 1)用于sslsupport的SslHandler。 I am using java's SslEngine.
我正在使用Java的SslEngine。
2) I extend the ByteToMessageCodec like this : 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);
}
}
If the channel is not writable when calling encode, I add a flush request so that the channel becomes writable again. 如果在调用编码时通道不可写,则添加刷新请求,以使通道再次可写。 Is this correct?
这个对吗?
3) The BusinessLogicHandler designates the processing to a thread pool which does asyncprocessing(involves IO) and writes back to the pipeline using the SocketChannel object. 3)BusinessLogicHandler将处理指定给一个线程池,该线程池执行asyncprocessing(涉及IO)并使用SocketChannel对象写回到管道。 All the writes are originated from the thread pool.
所有写操作均源自线程池。 And finally I add a flush() after all the writes so that all pending writes are flushed.
最后,我在所有写入之后添加了flush(),以便刷新所有未完成的写入。 Each write call involves a byte[] with a max size of 300bytes.
每个写调用都涉及一个byte [],最大大小为300bytes。 All the writes add upto around 20Mb totally.
所有写入的总和总计约为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
Because of this I find a delay in getting the content. 因此,我发现获取内容存在延迟。 The thread sleeps for a while to get the memory.
线程休眠一段时间以获取内存。 Could anyone kindly help me with this situation?
有人能帮助我解决这种情况吗? Thank you.
谢谢。
If the channel is not writable when calling encode, I add a flush request so that the channel becomes writable again.
如果在调用编码时通道不可写,则添加刷新请求,以使通道再次可写。 Is this correct?
这个对吗?
That doesn't look right to me. 在我看来,这不合适。 Your encoder isn't trying to write to the channel, it should just be trying to
byte[]
into a ByteBuf
. 您的编码器没有尝试写入通道,而应该只是尝试将
byte[]
写入ByteBuf
。 Your BusinessLogicHandler already made the decision to write or not and whether to flush or not. 您的BusinessLogicHandler已经做出是否写入以及是否刷新的决定。
Have you tried removing this code to see if it fixes your problem? 您是否尝试过删除此代码以查看它是否可以解决您的问题?
if (!ctx.channel().isWritable()) {
ctx.flush();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.