什么时候我应该将直接缓冲区与 Java NIO 一起用于网络 I/O 的简单规则?

问题描述 投票:0回答:2

具有用简单直接的方式解释复杂事物的天赋的人可以解决这个问题吗?在使用 Java NIO 进行网络 I/O 时,何时应该使用直接 ByteBuffers 与常规 ByteBuffers 以获得最佳性能?


例如:我应该读入堆缓冲区并从那里解析它,执行多次 get() (逐字节)还是应该将它读入直接缓冲区并从直接缓冲区解析?

java real-time css-selectors nio bytebuffer
2个回答
13
投票

在使用 Java NIO 进行网络 I/O 时,何时应该使用直接 ByteBuffers 与常规 ByteBuffers 以获得最佳性能?

直接缓冲区有很多优点

  • 避免在 Java 和本机内存之间传递额外的数据副本。
  • 如果它们被重新使用,只有使用过的页面才会变成真正的内存。这意味着您可以使它们比需要的大得多,它们只会浪费虚拟内存。
  • 您可以高效地以本机字节顺序访问多字节原语。 (基本上是一条机器码指令)

我应该读入堆缓冲区并从那里解析它,执行多次 get() (逐字节)还是应该将它读入直接缓冲区并从直接缓冲区解析?

如果你一次读取一个字节,你可能不会获得太多优势。但是,使用直接字节缓冲区,您可以一次读取 2 或 4 个字节,并一次有效地解析多个字节。

[实时] [选择器]

如果你正在解析实时数据,我会避免使用选择器。我发现使用阻塞 NIO 或忙等待 NIO 可以为您提供最低的延迟性能(假设您的连接数量相对较少,例如最多 20 个)

编辑:这是一个相对易于使用的高性能库,它使用阻塞式 NIO,您可以在 https://github.com/OpenHFT/Chronicle-Wire/tree/ea/src/main/java/net/ 上绘制openhft/chronicle/wire/channel


4
投票

当您只是复制数据时,直接缓冲区是最好的,比如从套接字复制到文件或 反之亦然, 因为数据不必遍历 JNI/Java 边界,它只是停留在 JNI 领域。如果您打算自己查看数据,那么直接缓冲区就没有意义了。

© www.soinside.com 2019 - 2024. All rights reserved.