java中BufferedInputStream BufferedOutputStream HeapByteBuffer DirectByteBuffer缓冲的区别

目录

BufferedInputStream

验证代码

运行时内存使用情况

HeapByteBuffer

验证代码

运行时内存使用情况

DirectByteBuffer

验证代码

运行时内存使用情况

总结


在之前写的文章基础上

https://blog.csdn.net/zlpzlpzyd/article/details/135247283

以 1GB 的文件为例比较

200

500

1024(1KB)

2KB

4KB

8KB

16KB

32KB

64KB

128KB

256KB

512KB

1MB

8MB

64MB

128MB

256MB

512MB

BufferedInputStream

761

665

450

448

458

457

282

251

220

204

204

203

487

549

627

723

785

911

HeapByteBuffer

6125

2677

1489

886

605

419

298

251

248

204

251

235

290

282

377

393

454

525

DirectByteBuffer

5786

2526

1419

849

553

380

265

204

173

188

173

173

203

188

219

253

220

292

以 2.45GB 的文件为例比较

200

500

1024(1KB)

2KB

4KB

8KB

16KB

32KB

64KB

128KB

256KB

512KB

1MB

8MB

64MB

128MB

256MB

512MB

BufferedInputStream

1458

1373

872

925

894

848

629

549

502

455

487

456

1098

549

627

723

785

911

HeapByteBuffer

12471

5419

2969

1838

1208

824

630

518

473

470

465

517

290

282

377

393

454

525

DirectByteBuffer

11792

5198

2857

1711

1162

801

514

455

392

361

361

377

203

188

219

253

220

292

由上面的测试结果得知,在缓冲区容量在 8KB、16KB、32KB、64KB、128KB、256KB、512KB 的时候三者耗时持平,但是耗时最短的是 128KB,耗时趋势是开口朝上的抛物线,缓冲区容量达到最佳阈值后再往上增加耗时反而增加。

鉴于 DirectByteBuffer 受限于 jvm 参数 -XX:MaxDirectMemorySize 的大小,默认值为 64MB,在运行时调整为大于 64MB 的缓冲大小后运行时间降低不明显。

BufferedInputStream

在 java 1.0 中添加的缓冲类

验证代码

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.Serializable;

public class TestBufferedInputStream implements Serializable {

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        File file = new File(Control.PATH);
        byte[] bs = new byte[Control.SIZE];
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
            while (bis.read(bs) != -1) {
//                    System.out.println(Arrays.toString(bs));
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        long duration = System.currentTimeMillis() - start;
        System.out.println(duration);
    }
}

运行时内存使用情况

使用 visualvm中的visual gc插件查看

HeapByteBuffer

在 java 1.4 中添加的缓冲类

验证代码

import java.io.File;
import java.io.FileInputStream;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class TestHeapByteBuffer implements Serializable {

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        File file = new File(Control.PATH);
        ByteBuffer byteBuffer = ByteBuffer.allocate(Control.SIZE);
        try (FileChannel fileChannel = new FileInputStream(file).getChannel()) {
            while (fileChannel.read(byteBuffer) > 0) {
                byteBuffer.clear();
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        long duration = System.currentTimeMillis() - start;
        System.out.println(duration);
    }
}

运行时内存使用情况

使用 visualvm中的visual gc插件查看

DirectByteBuffer

验证代码

import java.io.File;
import java.io.FileInputStream;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class TestDirectByteBuffer implements Serializable {

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        File file = new File(Control.PATH);
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(Control.SIZE);
        try (FileChannel fileChannel = new FileInputStream(file).getChannel()) {
            while (fileChannel.read(byteBuffer) > 0) {
                byteBuffer.clear();
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        long duration = System.currentTimeMillis() - start;
        System.out.println(duration);
    }
}

运行时内存使用情况

使用 visualvm中的visual gc插件查看

总结

HeapByteBuffer 和 DirectByteBuffer 是从 java 1.4 开始添加的类,之前的版本处理缓冲问题需要使用 BufferedInputStream 和 BufferedOutputStream,问题是针对 io 操作只能单向处理,HeapByteBuffer 和 DirectByteBuffer 结合 FileChannel 可以实现对文件的双向处理,即可以通过 FileChannel 实现读写功能。

参考链接

https://blog.csdn.net/flyzing/article/details/115388720

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值