DirectByteBuffer更快吗?

ByteBuffer.allocateDirect  vs  ByteBuffer.allocate 数组

操做系统的IO机制 缓存

    操做系统在内存区域上执行IO操做,这些内存区域是连续的字节。毫无疑问只有字节缓冲区才有资格参与IO操做的。一样操做系统会直接访问进程空间,包括JVM进程,传输数据。JVM内部,字节数组可能不是连续的,或者GC任意时刻会移动这些字节。Java内部数组是对象,对象内部数据存储的方式,是跟JVM实现相关的。 性能

引入Direct Buffer 优化

    出于这个缘由,引入了direct buffer。direct buffer就是为了和channel和本地IO例程交互。direct buffer的实现会尽可能让channel直接使用,本地操做系统代码可以直接读写。
spa

利弊 操作系统

    直接缓冲区一般是IO操做的最佳选择,是JVM可以使用的最高效的IO机制。non-direct缓冲区能够传递给channel,但一般会带来性能损耗。一般non-direct缓冲区不是本地IO操做的直接目标。若是让channel写non-direct ByteBuffer,channel会隐含的执行下列步骤:
设计

    建立临时的direct ByteBuffer
对象

    复制non-direct buffer中的内容到临时buffer
进程

    使用临时buffer执行IO操做
内存

    临时buffer不被引用,最终被垃圾收集

    这会潜在的致使每次IO操做中的缓冲区复制和Object Churn,这正是咱们想避免的。然而取决于实现,事情可能并不会这么坏。JVM运行时可能会缓存和重用direct缓冲区,或着其它技巧来提升吞吐量。若是建立只使用一次的缓冲区,这二者的区别并不明显。若是在高性能的场景中频繁使用buffer,那么最好使用direct缓冲区。

    direct缓冲区最适合IO,可是可能建立更加耗时。direct缓冲区使用的内存,绕过了JVM堆,经过本地代码调用分配。建立和销毁都要比驻留在JVM堆里的缓冲区更加耗时(依赖于操做系统和JVM实现)。direct缓冲区使用的内存不受垃圾收集的控制,由于它们在JVM堆的外部。

总结

    使用direct仍是non-direct的性能考虑依赖于JVM,操做系统,和应用代码。在JVM堆外分配内存,把应用受制于JVM不能监管的一些额外机制。让额外的一些机制起做用,必定要保证你得到了想要的效果。我推荐古老的设计哲学,“首先让他工做,而后让他更快”。不要提早担忧优化,首先关注应用的正确。JVM实现可能会执行一些优化,给你想要的性能,这样就免除了开发者的负担。

原文 From:http://stackoverflow.com/questions/5670862/bytebuffer-allocate-vs-bytebuffer-allocatedirect

相关文章
相关标签/搜索