在Java的NIO中,我们一般采用ByteBuffer缓冲区来传输数据,一般情况下我们创建Buffer对象是通过ByteBuffer的两个静态方法:

ByteBuffer.allocate(int capacity);
ByteBuffer.wrap(byte[] array);

查看相关的源码得到

public static ByteBuffer allocate(int capacity) {
if (capacity < 0)
throw new IllegalArgumentException();
return new HeapByteBuffer(capacity, capacity);
}
public static ByteBuffer wrap(byte[] array,
int offset, int length){
try {
return new HeapByteBuffer(array, offset, length);
} catch (IllegalArgumentException x) {
throw new IndexOutOfBoundsException();
}
}

我们可以很清楚的发现,这两个方法都是实例化HeapByteBuffer来创建的ByteBuffer对象,也就是heap buffer. 其实除了heap buffer以外还有一种buffer,叫做direct buffer。我们也可以创建这一种buffer,通过ByteBuffer.allocateDirect(int capacity)方法,查看JDK源码如下:

public static ByteBuffer allocateDirect(int capacity) {
return new DirectByteBuffer(capacity);
}
DirectByteBuffer(int cap) {                   // package-private

    super(-1, 0, cap, cap);
boolean pa = VM.isDirectMemoryPageAligned();
int ps = Bits.pageSize();
long size = Math.max(1L, (long)cap + (pa ? ps : 0));
Bits.reserveMemory(size, cap); long base = 0;
try {
base = unsafe.allocateMemory(size);
} catch (OutOfMemoryError x) {
Bits.unreserveMemory(size, cap);
throw x;
}
unsafe.setMemory(base, size, (byte) 0);
if (pa && (base % ps != 0)) {
// Round up to page boundary
address = base + ps - (base & (ps - 1));
} else {
address = base;
}
cleaner = Cleaner.create(this, new Deallocator(base, size, cap));
att = null;
}

那么heap buffer和direct buffer有什么区别呢?

heap buffer这种缓冲区是分配在堆上面的,直接由Java虚拟机负责垃圾回收,可以直接想象成一个字节数组的包装类。

direct buffer则是通过JNI在Java的虚拟机外的内存中分配了一块缓冲区(所以即使在运行时通过-Xmx指定了Java虚拟机的最大堆内存,还是可以实例化超出该大小的Direct ByteBuffer),该块并不直接由Java虚拟机负责垃圾回收收集,但是在direct buffer包装类被回收时,会通过Java Reference机制来释放该内存块。(但Direct Buffer的JAVA对象是归GC管理的,只要GC回收了它的JAVA对象,操作系统才会释放Direct Buffer所申请的空间)

两者各有优劣势:direct buffer对比 heap buffer:

劣势:创建和释放Direct Buffer的代价比Heap Buffer得要高;

优势:当我们把一个Direct Buffer写入Channel的时候,就好比是“内核缓冲区”的内容直接写入了Channel,这样显然快了,减少了数据拷贝(因为我们平时的read/write都是需要在I/O设备与应用程序空间之间的“内核缓冲区”中转一下的)。而当我们把一个Heap Buffer写入Channel的时候,实际上底层实现会先构建一个临时的Direct Buffer,然后把Heap Buffer的内容复制到这个临时的Direct Buffer上,再把这个Direct Buffer写出去。当然,如果我们多次调用write方法,把一个Heap Buffer写入Channel,底层实现可以重复使用临时的Direct Buffer,这样不至于因为频繁地创建和销毁Direct Buffer影响性能。

结论:Direct Buffer创建和销毁的代价很高,所以要用在尽可能重用的地方。 比如周期长传输文件大采用direct buffer,不然一般情况下就直接用heap buffer 就好。

Refer:

http://blog.csdn.net/u010853261/article/details/53464322

https://www.jianshu.com/p/007052ee3773

http://blog.csdn.net/xieyuooo/article/details/7547435

NIO中的heap Buffer和direct Buffer区别的更多相关文章

  1. 转载C#中堆(heap)和栈(stack)的区别

    转载原地址  http://www.cnblogs.com/wangshenhe/archive/2013/02/18/2916275.html [转]C#堆和栈的区别 理解堆与栈对于理解.NET中的 ...

  2. Java中堆(heap)和栈(stack)的区别

    简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配. 当在一段代码块定义一个变量时,Java就在栈中为这个变量分 ...

  3. Direct Buffer介绍

    Direct Buffer 前言 上篇文章Buffer末尾中谈到堆内Buffer(Heap Buffer)和直接Buffer(Direct Buffer)的概念,但是却一笔带过,并未涉及其细节,这篇文 ...

  4. Java网络编程和NIO详解8:浅析mmap和Direct Buffer

    Java网络编程与NIO详解8:浅析mmap和Direct Buffer 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NI ...

  5. Java网络编程与NIO详解8:浅析mmap和Direct Buffer

    微信公众号[黄小斜]作者是蚂蚁金服 JAVA 工程师,目前在蚂蚁财富负责后端开发工作,专注于 JAVA 后端技术栈,同时也懂点投资理财,坚持学习和写作,用大厂程序员的视角解读技术与互联网,我的世界里不 ...

  6. JVM--你常见的jvm 异常有哪些? 代码演示:StackOverflowError , utOfMemoryError: Java heap space , OutOfMemoryError: GC overhead limit exceeded, Direct buffer memory, Unable_to_create_new_native_Thread, Metaspace

    直接上代码: public class Test001 { public static void main(String[] args) { //java.lang.StackOverflowErro ...

  7. Java NIO中的Buffer 详解

    Java NIO中的Buffer用于和NIO通道进行交互.如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的.缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这块内存被包装成NIO ...

  8. Java NIO中的缓冲区Buffer(一)缓冲区基础

    什么是缓冲区(Buffer) 定义 简单地说就是一块存储区域,哈哈哈,可能太简单了,或者可以换种说法,从代码的角度来讲(可以查看JDK中Buffer.ByteBuffer.DoubleBuffer等的 ...

  9. java NIO中的buffer和channel

    缓冲区(Buffer):一,在 Java NIO 中负责数据的存取.缓冲区就是数组.用于存储不同数据类型的数据 根据数据类型不同(boolean 除外),提供了相应类型的缓冲区:ByteBufferC ...

随机推荐

  1. R语言编程艺术(5)R语言编程进阶

    本文对应<R语言编程艺术> 第14章:性能提升:速度和内存: 第15章:R与其他语言的接口: 第16章:R语言并行计算 ================================== ...

  2. 2017 JUST Programming Contest 2.0 题解

    [题目链接] A - On The Way to Lucky Plaza 首先,$n>m$或$k>m$或$k>n$就无解. 设$p = \frac{A}{B}$,$ans = C_{ ...

  3. 011.Zabbix的拓扑创建

    一 Map简介 Map的作用是将各种设备用网络拓扑图的方式展示,在Zabbix中,拓扑的展示通过手动方式添加. 二 Map的添加 2.1 添加Map的背景图 #在添加Map之前可谓Map添加一个背景图 ...

  4. Mac idea 快捷键

    Mac键盘符号和修饰键说明 ⌘ Command⇧ Shift⌥ Option⌃ Control↩︎ Return/Enter⌫ Delete⌦ 向前删除键(Fn+Delete)↑ 上箭头↓ 下箭头← ...

  5. NOIP练习赛题目6

    长途旅行 难度级别:A: 运行时间限制:3000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 JY 是一个爱旅游的探险家,也是一名强迫症患者.现在JY 想要在C ...

  6. 2015 年度新增开源软件排名 TOP 100 - 开源中国社区

    2015 年度新增开源软件排名 TOP 100 - 开源中国社区 39.ABTestingGateway http://www.oschina.net/news/69808/2015-annual-r ...

  7. webdings 和 wingdings 字体

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. 谢宝友 LINUX 内核专家-----LINUX内核注释

    http://download.csdn.net/user/xiebaoyou http://blog.chinaunix.net/uid/25845340.html

  9. CRM上线之路 走上了CRM实施顾问-第12天上班 -第三周

    今天是周五,<CRM初期需求说明>是经理们商讨的,总共2张纸,根据两次会议,我写了<CRM需求说明>总共18面. 这是这周的工作汇报,其实,报告是我一天内写出来的,中午饭都没吃 ...

  10. 3I工作室的成员在2013年(第6届)中国大学生计算机设计大赛总决赛中荣获全国二等奖

    在暑假举行的2013年(第6届)中国大学生计算机设计大赛中,我院的参赛作品<毕业生论文选导系统>(作者:祝丽艳/许明涛:指导老师:元昌安/彭昱忠)入围总决赛,并荣获全国二等奖. 2013年 ...