9

我在 SO 和其他地方看到的每个 Java 循环字节缓冲区实现都没有扩展 java.nio.ByteBuffer,这对我来说是与 SocketChannel 一起使用所必需的。有谁知道扩展 ByteBuffer 的开源实现。我尝试自己编写,但是当我意识到位置和剩余功能是最终的并且我要覆盖它们以调整头部并防止缓冲区溢出异常时,我陷入了困境。在通过套接字通道发送 5000 条消息时,每条消息都需要我将内容复制到线性缓冲区的头部,这增加了每条消息大约 450 毫秒或 90 微秒(其中包含 10 个数据包,因此每个数据包 9 微秒)。现在我能想到的唯一可行的方法是覆盖每一个方法并重写所有内容。有任何想法吗?

4

4 回答 4

7

您可以使缓冲区比一条消息大得多,而不是创建一个循环缓冲区。假设最大消息大小为 N 字节。创建一个 100 * N 字节的缓冲区,只有在剩余少于 N 字节时才会 compact() ByteBuffer。这将使复制量减少 100 倍。

另一个优化是在没有剩余数据时压缩() ByteBuffer,因为这非常快。

于 2011-03-04T07:45:18.143 回答
7

你不能扩展 java.nio.ByteBuffer,就这么简单。c-tor 是包私有的。它不会起作用,b/c 的主要思想是将地址传递给一些 C 代码。你也不能覆盖任何东西,因为许多方法都是最终的。ByteBuffers 是为速度而设计的,有些决定可能看起来很奇怪,但它们没问题。

java.nio.channels.GatheringByteChannel值得一试,java.nio.channels.ScatteringByteChannel尽管有相当多的实现依赖(本机 C)使它们有用。

于 2011-03-04T10:00:48.980 回答
2

我们可以试试这个,因为它是 apache 许可证

https://svn.apache.org/repos/asf/etch/releases/release-1.0.0/util/src/main/java/etch/util/CircularByteBuffer.java

于 2013-04-09T16:12:00.987 回答
0

我会利用方法 ByteBuffer.wrap()。快速查看Dean Hiller 先生之前发布的Cisco 的实现,您可以将put() 替换为getWriteBuffer(),它会返回一个ByteBuffer,它将包装在它可以写入的缓冲区中的部分。

相同的逻辑可以应用于阅读部分。

它的优点是不必压缩,这可能会很昂贵,具体取决于 ByteBuffer 中的字节数,代价是使解析逻辑复杂化:您可以获得包装最后一个 ByteBuffer 的消息的第一部分底层循环缓冲区的区域。要获取消息的第二部分,需要再次读取以将循环缓冲区开头的字节数组包装到另一个 ByteBuffer 中。

于 2014-01-29T17:21:15.763 回答