Java中ByteBuffer的allocate方法 和allocateDirect方法的区别和选用原则解析

 更新时间:2023年12月22日 10:18:41   作者:Shujie_L  
在Java中,ByteBuffer是java.nio包中的一个类,用于处理字节数据,ByteBuffer提供了两种方式来分配内存:allocate和allocateDirect,这篇文章主要介绍了Java中ByteBuffer的allocate方法 和allocateDirect方法的区别和选用原则 ,需要的朋友可以参考下

背景

公司开发一个商用的支付应用。写协议的时候需要用到byte类型数组来填充协议的报文数据。在调研了JDK各个类库之后,最终选用Java类库中的ByteBuffer

在Java中,ByteBufferjava.nio包中的一个类,用于处理字节数据。ByteBuffer提供了两种方式来分配内存:allocateallocateDirect

    /**
     * Allocates a new direct byte buffer.
     *
     * <p> The new buffer's position will be zero, its limit will be its
     * capacity, its mark will be undefined, and each of its elements will be
     * initialized to zero.  Whether or not it has a
     * {@link #hasArray backing array} is unspecified.
     *
     * @param  capacity
     *         The new buffer's capacity, in bytes
     *
     * @return  The new byte buffer
     *
     * @throws  IllegalArgumentException
     *          If the <tt>capacity</tt> is a negative integer
     */
    public static ByteBuffer allocateDirect(int capacity) {
        // Android-changed: Android's DirectByteBuffers carry a MemoryRef.
        // return new DirectByteBuffer(capacity);
        DirectByteBuffer.MemoryRef memoryRef = new DirectByteBuffer.MemoryRef(capacity);
        return new DirectByteBuffer(capacity, memoryRef);
    }
    /**
     * Allocates a new byte buffer.
     *
     * <p> The new buffer's position will be zero, its limit will be its
     * capacity, its mark will be undefined, and each of its elements will be
     * initialized to zero.  It will have a {@link #array backing array},
     * and its {@link #arrayOffset array offset} will be zero.
     *
     * @param  capacity
     *         The new buffer's capacity, in bytes
     *
     * @return  The new byte buffer
     *
     * @throws  IllegalArgumentException
     *          If the <tt>capacity</tt> is a negative integer
     */
    public static ByteBuffer allocate(int capacity) {
        if (capacity < 0)
            throw new IllegalArgumentException();
        return new HeapByteBuffer(capacity, capacity);
    }

区别

这两种方式分别对应于不同的内存分配策略,具有不同的优劣势。

1. allocate:

  • 使用allocate方法分配的内存是在Java虚拟机的堆内存中。
  • ByteBuffer.allocate(capacity)分配的是非直接缓冲区(non-direct buffer)。
  • 非直接缓冲区的操作会在Java堆内存中进行,数据的读写会通过Java堆来传递。
```java
ByteBuffer buffer = ByteBuffer.allocate(1024);
```

2. allocateDirect:

  • 使用allocateDirect方法分配的内存是在操作系统的本地内存中,而不是在Java堆内存中。
  • ByteBuffer.allocateDirect(capacity)分配的是直接缓冲区(direct buffer)。
  • 直接缓冲区的操作可以通过本地I/O传递,避免了在Java堆和本地堆之间的数据传输,可能在某些情况下提供更好的性能。
```java
ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);
```

总结

选择使用哪种方式取决于应用的需求和性能特征:

  • allocate: 适用于较小的缓冲区,对内存占用不太敏感的情况。由于是在Java堆上分配,垃圾回收器能够管理这部分内存,但可能会有一些性能开销。
  • allocateDirect: 适用于需要较大缓冲区或对性能要求较高的情况。由于是在本地内存上分配,可能减少了一些垃圾回收器的开销,但在分配和释放直接缓冲区时可能涉及到一些本地资源的操作。

在使用allocateDirect时需要谨慎,因为它可能占用较多的本地内存,过度使用可能导致本地内存耗尽。

在选用这两种技术方案中哪一种的时候需要根据具体的应用场景和需求权衡两者之间的取舍。

到此这篇关于Java中ByteBuffer的allocate方法 和allocateDirect方法的区别和选用原则 的文章就介绍到这了,更多相关Java ByteBuffer的allocate方法 和allocateDirect方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java中的FutureTask实现代码实例

    Java中的FutureTask实现代码实例

    这篇文章主要介绍了Java中的FutureTask手写代码实例,FutureTask是Future的实现,用来异步任务的获取结果,可以启动和取消异步任务,查询异步任务是否计算结束以及获取最终的异步任务的结果,需要的朋友可以参考下
    2023-12-12
  • Java中static与instance的区别及作用详解

    Java中static与instance的区别及作用详解

    这篇文章主要为大家介绍了Java中static与instance的区别及作用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • java错误: 不支持发行版本 22的简单解决方法

    java错误: 不支持发行版本 22的简单解决方法

    这篇文章主要给大家介绍了关于java错误: 不支持发行版本 22的简单解决方法,这个错误通常是由于Java版本不兼容导致的,请检查您的项目所使用的Java版本是否与您当前安装的Java版本一致,需要的朋友可以参考下
    2024-06-06
  • commons fileupload实现文件上传的实例代码

    commons fileupload实现文件上传的实例代码

    这篇文章主要介绍了commons fileupload实现文件上传的实例代码,包括文件上传的原理分析等相关知识点,本文给大家介绍的非常详细,具有参考借鉴价值,感兴趣的朋友一起看看吧
    2016-10-10
  • java 如何查看jar包加载顺序

    java 如何查看jar包加载顺序

    这篇文章主要介绍了java 如何查看jar包加载顺序,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Java中List集合去重的几种方式详细解析

    Java中List集合去重的几种方式详细解析

    这篇文章主要介绍了Java中List集合去重的几种方式详细解析,在日常的业务开发中,偶尔会遇到需要将 List 集合中的重复数据去除掉的场景,那么今天我们来看看几种LIst集合去重的方式,需要的朋友可以参考下
    2023-11-11
  • java设计模式之工厂方法模式

    java设计模式之工厂方法模式

    这篇文章主要为大家详细介绍了java设计模式之工厂方法模式,什么是java工厂方法模式,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • 精通Java接口的使用与原理

    精通Java接口的使用与原理

    接口,在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法
    2022-03-03
  • java 非对称加密算法DH实现详解

    java 非对称加密算法DH实现详解

    这篇文章主要介绍了java 非对称加密算法DH实现详解 ,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • springcloud连接远程nacos失败显示localhost服务连接失败的问题解决

    springcloud连接远程nacos失败显示localhost服务连接失败的问题解决

    这篇文章主要介绍了springcloud连接远程nacos失败显示localhost服务连接失败的问题解决,文中有详细的代码示例供大家参考,对大家解决问题有一定的帮助,需要的朋友可以参考下
    2024-03-03

最新评论