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直接使用,本地操作系统代码能够直接读写。

利弊

    直接缓冲区通常是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

转载于:https://my.oschina.net/astute/blog/93902

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值