Java中可调整大小的最佳字节缓冲区是什么?

12

我需要一个Java字节缓冲区类,用于单线程使用。缓冲区应在满时调整大小,而不是抛出异常或其他情况。对我来说非常重要的问题是性能。

你推荐什么?

补充说明: 目前我正在使用ByteBuffer,但它无法调整大小。我需要一个可以调整大小的字节缓冲区。


附注:微基准测试和字节缓冲区笔记:http://www.evanjones.ca/software/java-bytebuffers.html - miku
如何将性能和单线程使用结合起来,普通的byte[]轻松胜任任何事情。 - bestsss
2
无法使用byte[],因为我不知道要写入的数据长度。 - Worker
当然可以,只需要扩大一下容量就行了 :)。然后你就可以轻松地将 ByteBuffer 包装起来。我个人使用的是 ByteArrayOutputStream 的子类(buf 和 count 是受保护的),完成后我可以将 byte[] 包装成 ByteBuffer,类似于 wrap(buf, 0, count)。 - bestsss
3个回答

10

有没有不使用普通的ByteArrayOutputStream的原因?

正如上面的miku所提到的,Evan Jones对不同类型进行了评论并显示它非常依赖于应用程序。因此,在不知道更多细节的情况下,很难推测。

我会从ByteArrayOutputStream开始,仅当分析表明它是您的性能瓶颈时才转移到其他内容。通常,当您认为缓冲区代码是瓶颈时,它实际上是网络或其他I / O - 等到分析表明需要优化之前,不要浪费时间找到替代品。

如果您正在转移到其他内容,则需要考虑的其他因素:

  • 您已经说过您正在使用单线程,因此不需要BAOS的同步
  • 缓冲区被填充和喂入什么? 如果任何一端已经连接使用Java NIO,那么使用直接ByteBuffer非常有效。
  • 您是否使用循环缓冲区或普通线性缓冲区? 如果是,则Ostermiller Utils相当有效,并且是GPL的。

@MinimeDJ - 我不确定你在做什么,但是“可能会有一些性能影响”与“存在性能问题”相差甚远。 - Nick Fortescue
Nick Fortescue,为您的出色回答点赞。我正在将对象序列化以存储到NOSQL数据库中。目前我使用ByteBuffer。我会尝试使用BAOS来查看其性能如何。 - Worker
@MinimeDJ,偏向锁(synchronized Java关键字)第一次需要一个CAS操作,然后是比较/跳转(大约1-3个CPU周期),对于单线程使用来说实际上是免费的。 - bestsss
@Nick,你如何确定ByteArrayOutputStream是瓶颈。这不能通过普通的分析器完成。由于代码路径非常小,并且不能保证在那里有“安全点”。如果增强并添加计数器(等等),则优化将不同。微观分析很难做到完美。 - bestsss

2

您可以使用直接ByteBuffer。 直接内存首先使用虚拟内存,只有在使用时才分配给应用程序。 也就是说,它使用的主存量会自动调整大小。

创建一个比您需要的更大的直接ByteBuffer,它只会消耗您使用的部分。


不错哦,对于页面错误自动处理 :D 但是直接内存的数量是有限制的(当然可以设置得足够高)。由于分配和特别是释放DirectByteBuffers相当昂贵,因此需要对它们进行池化处理。 - bestsss

2

您还可以编写手动代码来持续检查缓冲区内容,如果满了,则创建一个更大尺寸的新缓冲区并将所有数据移动到该新缓冲区中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接