JAVA NIO 直接缓冲区和非直接缓冲区

非直接缓冲区

1.分配在java 堆内存中

2.分配非直接缓冲区要比分配直接缓冲区的效率跟高

3.非直接缓冲区需要进行垃圾回收,如果处理不当的话,会对性能造成影响

直接缓存区

非直接缓冲区的特点

1.非直接缓存区是在java 堆内存之外分配,直接在本地内存中分配。

2.分配直接缓冲区比分配非直接缓冲区更加昂贵,效率更低

3.它是直接和本地I/O操作接口,在某些I/O繁重的情况下,可以带来更好的性能

4.不存在在 java 堆内存中,能够减少jvm 垃圾回收器的负担。

java如何分配直接缓存区和非直接缓存区?

查看jdk API doc 发现,这有ByteBuffer 中可以有分配直接缓冲区的方法,那么为什么其它Buffer中没有呢,没有的话其它数据类型如何可以操作直接内存呢?

使用 ByteBuffer 中的方法分配直接缓冲区和非直接缓冲区

    public static void main(String[] args) {
        // 分配非直接缓冲区 10 
        ByteBuffer buffer = ByteBuffer.allocate(10);  

        // 分配非直接缓冲区 10 
        ByteBuffer directBuffer = ByteBuffer.allocateDirect(10); 
        
    }

 非直接内存分配方法内部实现

 直接内存分配方法内部实现

那么其它的基本数据类型的缓冲区如何可以操作直接内存呢?

    public static void main(String[] args) {
        ByteBuffer buffer = ByteBuffer.allocate(10);
        ByteBuffer directBuffer = ByteBuffer.allocateDirect(10);
        // 在 ByteBuffer 中有一系类的 asxxxBuffer() 的方法,将ByteBuffer 直接缓冲区
        // 装换为其它基本数据类型的直接缓存区
        LongBuffer longBuffer = directBuffer.asLongBuffer();

    }

直接缓存区和非直接缓存区的性能测试对比

分配缓冲区对比

package NIO.buffer;

import java.nio.ByteBuffer;

public class TestBuffer {

    public static final String str = "hello world";

    public static void main(String[] args) {
        testBuffer(100000);
        testDirectBuffer(100000);

    }

    private static void testBuffer(int count) {

        long start = System.currentTimeMillis();
//        ByteBuffer allocate = ByteBuffer.allocate(str.length() * count);
        for (int i = 0; i < count; i++) {
            ByteBuffer allocate = ByteBuffer.allocate(count);
//            allocate.put(str.getBytes());
        }
//        allocate.flip();
//        for (int i = 0; i < count; i++) {
//            allocate.getChar();
//        }
        long end = System.currentTimeMillis();
        System.out.println("时间" + (end - start));
    }

    private static void testDirectBuffer(int count) {
        long start = System.currentTimeMillis();
//        ByteBuffer allocate = ByteBuffer.allocateDirect(str.length() * count);
        for (int i = 0; i < count; i++) {
            ByteBuffer allocate = ByteBuffer.allocateDirect(count);
//            allocate.put(str.getBytes());
        }
//        allocate.flip();
//        for (int i = 0; i < count; i++) {
//            allocate.getChar();
//        }
        long end = System.currentTimeMillis();
        System.out.println("时间" + (end - start));
    }
}

结果:

时间2031
时间21933

I/O 对比

package NIO.buffer;

import java.nio.ByteBuffer;

public class TestBuffer {

    public static final String str = "hello world";

    public static void main(String[] args) {
        // 结果:时间8325
        // 结果:时间8026
        testBuffer(100000000);

        testDirectBuffer(100000000);
        
    }

    private static void testBuffer(int count) {

        long start = System.currentTimeMillis();
        ByteBuffer allocate = ByteBuffer.allocate(str.length() * count);
        for (int i = 0; i < count; i++) {
            allocate.put(str.getBytes());
        }
        allocate.flip();
        for (int i = 0; i < count; i++) {
            allocate.getChar();
        }
        long end = System.currentTimeMillis();
        System.out.println("时间" + (end - start));
    }

    private static void testDirectBuffer(int count) {
        long start = System.currentTimeMillis();
        ByteBuffer allocate = ByteBuffer.allocateDirect(str.length() * count);
        for (int i = 0; i < count; i++) {
            allocate.put(str.getBytes());
        }
        allocate.flip();
        for (int i = 0; i < count; i++) {
            allocate.getChar();
        }
        long end = System.currentTimeMillis();
        System.out.println("时间" + (end - start));
    }
}

结果:

1.两个方法一起执行:

       // 结果:  时间8464
       // 结果:  时间6205

2.先后执行

        // 结果:时间8325
        // 结果:时间8026

总结:

1.非直接内存分配缓冲区的时间小于直接缓冲区的分配时间

2.在I/O 反面 直接缓冲区的效率要比非直接缓冲区的效率跟高

在对比两个东西的效率的时候,我们有时候就会陷入到单一的思维中,就是那个效率跟高,那个更好,其实这个是不对的(我最开始就是这样想的),需要全面的考虑和了解,才能够下判断和决策,选择对应的工具(方法)来解决具体(实际碰到)的问题。

参考:https://www.cnblogs.com/xing901022/p/5243657.html?spm=a2c6h.12873639.article-detail.8.3045438fuWfOLb

 java.nio (Java SE 17 & JDK 17)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值