9

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


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

4

2 回答 2

12

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

直接缓冲区有许多优点

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

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

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

[实时] [选择器]

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

于 2012-08-30T07:39:34.360 回答
4

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

于 2012-08-30T00:00:09.343 回答