我使用netty 4编写了一个简单的http客户端。据我所知,如果我使用HeapBuffer,当我在ChannelInboundHandler中获取ByteBuffer时
@Override
public void channelRead(ChannelHandlerContext ctx, final ByteBuf msg) throws Exception {
// do nothing with the msg
}
Run Code Online (Sandbox Code Playgroud)
来自网站的字节应该是一个类似的过程(即使我不调用 ByteBuf.read)
socket -> kernel space -> user space
Run Code Online (Sandbox Code Playgroud)
这些字节应该在java堆中,对吧?
我想知道如果我使用DirectBuffer,当“channelRead”触发时,如果我不调用ByteBuf.read,来自网站的字节在哪里,它们是在内核空间还是在用户空间?它是否比我使用 HeapBuffer 少了一次内存复制(因为它不会复制到用户空间)?
DirectBuffer 分配在用户空间中,但位于 JVM 堆之外。请注意,在谈论套接字 I/O 时,这仍然涉及从内核缓冲区到用户空间缓冲区的复制。然而,它确实消除了对然而,它确实消除了JVM 需要用来向堆复制或从堆复制的中间因此,I/O 操作可以直接发生在本机用户空间缓冲区上,就像运行 C 代码一样。
回复:您的netty代码片段,当netty调用时channelRead,数据已经被读入ByteBuf(在用户空间中)。如果你希望数据保留在socket缓冲区中(例如,实现反压),你可以调用channel.config.setAutoRead(false)来告诉netty不要自动从socket缓冲区读取。