开发者

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

开发者 https://www.devze.com 2023-12-23 10:55 出处:网络 作者: Shujie_L
目录背景区别1. allocate:2. allocateDirect:总结背景 公司开发一个商用的支付应用。写协议的时候需要用到byte类型数组来填充协议的报文数据。在调研了JDK各个类库之后,最终选用Java类库中的ByteBuffer。
目录
  • 背景
  • 区别
    • 1. allocate:
    • 2. 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 tLtAKOnxanew IllegalArgumentException();
            return new HeapByteBuffer(capacity, capacity);
        }

    区别

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

    1. alhttp://www.devze.comlocate:

    • 使用allocate编程客栈法分配的内存是在Java虚拟机的堆内存中。
    • ByteBuffer.allocate(capacity)分配的是非直接缓冲区(non-direct buffer)。
    • 非直接缓js冲区的操作会在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方法 和alloca编程teDirect方法内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消