ByteBuffer回收类
我想知道如何编写一个 ByteBuffer
回收类,它可以为我提供一个 ByteBuffer
,它至少与指定长度一样大,并且可以锁定正在使用的 ByteBuffer 对象,以防止在我的代码使用它们时使用它们。这将防止一遍又一遍地重新构建 DirectByteBuffers 等,而是使用现有的。是否有现有的 Java 库可以非常有效地做到这一点?我知道 Javolution 可以处理对象回收,但是在满足要求的情况下,这是否扩展到此上下文中的 ByteBuffer 类?
I'm wondering how I'd code up a ByteBuffer
recycling class that can get me a ByteBuffer
which is at least as big as the specified length, and which can lock up ByteBuffer
objects in use to prevent their use while they are being used by my code. This would prevent re-construction of DirectByteBuffers
and such over and over, instead using existing ones. Is there an existing Java library which can do this very effectively? I know Javolution can work with object recycling, but does that extend to the ByteBuffer
class in this context with the requirements set out?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
首先,更重要的是在使用模式上更加保守。例如,有很多代码显示在每个 OP_READ 上分配新的 ByteBuffer。这太疯狂了。每个连接最多只需要两个 ByteBuffer,一个用于输入,一个用于输出,并且根据您正在执行的操作,您可以只使用一个。在极其简单的情况下,例如回显服务器,您可以为整个应用程序使用一个 BB。
我会调查这一点,而不是用另一层软件来掩盖裂缝。
It would be more to the point to be more conservative in your usage patterns in the first place. For example there is lots of code out there that shows allocation of a new ByteBuffer on every OP_READ. This is insane. You only need two ByteBuffers at most per connection, one for input and one for output, and depending on what you're doing you can get away with exactly one. In extremely simple cases like an echo server you can get away with one BB for the entire application.
I would look into that rather than paper over the cracks with yet another layer of software.
这只是建议,不是答案。如果您确实为 DirectByteBuffer 实现了一些缓存,那么请务必阅读有关 GC 影响的信息,因为垃圾收集器不会跟踪 DirectByteBuffer 消耗的内存。
一些参考资料:
一个主题 - 以 Stack Overflow 的方针为特色
关于同一主题的博客文章
以及后续
This is just advice, not an answer. If you do implement some caching for DirectByteBuffer, then be sure to read about the GC implications, because the memory consumed by DirectByteBuffer is not tracked by the garbage collector.
Some references:
A thread - featuring Stack Overflow's tackline
A blog post on the same subject
And the followup
通常,您会结合使用 ThreadLocal 和 SoftReference 包装器。前者简化了同步(本质上消除了对它的需要);如果没有足够的内存,后者可以使缓冲区可回收(请记住有关直接缓冲区的 GC 问题的其他评论)。其实很简单:检查SoftReference是否有足够大的缓冲区;如果没有,则分配;如果是,请明确参考。完成后,重新设置指向缓冲区的引用。
另一个问题是,与常规的 byte[] 相比,是否需要 ByteBuffer。许多开发人员假设 ByteBuffer 在性能方面更好,但这种假设通常没有实际数据的支持(即测试是否存在性能差异,以及性能差异的方向)。 byte[] 通常更快的原因是访问它的代码可以更简单,HotSpot 更容易有效地进行 JIT。
Typically, you would use combination of ThreadLocal and SoftReference wrapper. Former to simplify synchronization (eliminate need for it, essentially); and latter to make buffer recycleable if there's not enough memory (keeping in mind other comments wrt. GC issues with direct buffers). It's actually quite simple: check if SoftReference has buffer with big enough size; if not, allocate; if yes, clear reference. Once you are done with it, re-set reference to point to buffer.
Another question is whether ByteBuffer is needed, compared to regular byte[]. Many developers assume ByteBuffers are better performance-wise, but that assumption is not usually backed by actual data (i.e. testing to see if there is performance difference, and to what direction). Reason why byte[] may often be faster is that code accessing it can be simpler, easier for HotSpot to efficiently JIT.