NIO ByteBuffer的allocate与allocateDirect区别(HeapByteBuffer与DirectByteBuffer的区别)

article/2025/11/1 14:39:47

参考:https://blog.csdn.net/zhxdick/article/details/81084672

其中allocateDirect分配的字节缓冲区用中文叫做直接缓冲区(DirectByteBuffer),用allocate分配的ByteBuffer叫做堆字节缓冲区(HeapByteBuffer)..

其实根据类名就可以看出,HeapByteBuffer所创建的字节缓冲区就是在jvm堆中的,即内部所维护的java字节数组。而DirectByteBuffer是直接操作操作系统本地代码创建的内存缓冲数组(c、c++的数组)。

一、

由于DirectByteBuffer操作的缓冲区是通过操作系统本地代码创建的,对于java来说创建和销毁DirectByteBuffer更消耗性能。而HeapByteBuffer内部是直接创建的java数组,对于java来说更快。可以根据下面的测试代码测试:

public static void directAndHeapSpeedCompare(){int length=1000000;directExecuteTime(length);heapExecuteTime(length);}private static void directExecuteTime(int length){long startTime=System.currentTimeMillis();ByteBuffer[] byteBufferArray = new ByteBuffer[length];for (int i = 0; i <length ; i++) {byteBufferArray[i]=ByteBuffer.allocateDirect(1024);}long endTime=System.currentTimeMillis();System.out.println("创建"+length+"个DirectByteBuffer所消耗的时间:"+(endTime-startTime));}private static void heapExecuteTime(int length){long startTime=System.currentTimeMillis();ByteBuffer[] byteBufferArray = new ByteBuffer[length];for (int i = 0; i <length ; i++) {byteBufferArray[i]=ByteBuffer.allocate(1024);}long endTime=System.currentTimeMillis();System.out.println("创建"+length+"个HeapByteBuffer所消耗的时间:"+(endTime-startTime));}

我的测试结果是:

创建1000000个DirectByteBuffer所消耗的时间:1443
创建1000000个HeapByteBuffer所消耗的时间:925

二、那么为什么创建DirectByteBuffer比HeapByteBuffer性能差却还使用DirectByteBuffer呢?

答:创建DirectByteBuffer的确不如HeapByteBuffer快,但是本地IO(从操作系统本地获取数据,比如FileChannel、SocketChannel网络数据)时,使用DirectByteBuffer比HeapByteBuffer少复制一次(java堆内存复制到操作系统内存,具体请继续看)

看源码,这里以FileChannel实现类FileChannelImpl.read中为例:

而该read方法实际是使用IOUtil.read

具体解析:

(1)当从FileChannel读取数据到DirectByteBuffer时,是直接使用DirectByteBuffer相关的本地方法。把数据从本地磁盘中拿出来写入到DirectByteBuffer所对应的堆外内存中。

(2)当从FileChannel读取数据到HeapByteBuffer时,需要先把数据读取到DirectByteBuffer中,再继续从DirectByteBuffer中把数据复制heapByteBuffer。(即先把数据从本地磁盘复制到堆外内存,然后再从堆外内存复制到堆内存中)

所以,当java程序数据需要频繁与本地io(本地磁盘、socket传输数据时),使用HeapByteBuffer需要读取时要多复制一次数据(即从DirectByteBuffer再复制到heapByteBuffer)。再加上写数据到本地时,又要再从HeapByteBuffer复制到另一个DirectByteBuffer,多了两次复制。

举个具体的例子:

比如从socket读取数据到文件:

(1)使用DirectByteBuffer时:网络->DirectByteBuffer->文件

(2)使用HeadByteBuffer时:网络->新的DirectByteBuffer->HeadByteBuffer->另一个新的DirectByteBuffer->文件

也就是使用HeadByteBuffer时,要从java堆内存(字节数组)里面再读取一遍。。相当于多了两个步骤了

 

另一个原因是:

HeapByteBuffer底层其实是java的字节数组,而java字节数组是一个java对象,对象的内存是由jvm的堆进行管理的,那么不可避免的是GC时年轻代的eden、suvivor到老年代的各种复制以及回收。。。当字节数组比较小的时候还好说,如果是大对象,那么对于jvm的GC来说是一个很大的负担。。而使用DirectByteBuffer,则是把字节数组交给操作系统管理(堆外内存),就可以极大的减少jvm的负担了

 

综上所述:

什么情况下使用DirectByteBuffer(ByteBuffer.allocateDirect(int))?

1、频繁的native IO,即java程序与本地磁盘、socket传输数据。

2、不需要经常创建和销毁DirectByteBuffer对象(执行cpp的构造和析构代价大)(使用池复用DirectByteBuffer

3、DirectByteBuffer不会占用堆内存。。也就是不会受到堆大小限制,只在DirectByteBuffer对象被回收后才会释放该缓冲区。

4、大文件造成大对象,对GC负担比较重的情况

 

什么情况下使用HeapByteBuffer(ByteBuffer.allocate(int))?

其实除了上述的DirectByteBuffer使用场景之外的,基本可以用HeapByteBuffer。。

即:

(1)数据仅在java程序中流转传输,不与本地进行IO

(2)容量低,对GC负担低。快速回收

 

 

 


http://chatgpt.dhexx.cn/article/bWui0BlL.shtml

相关文章

【系统分析师】论文

文章目录 一、论文框架二、相关素材概览2.1 常见开发模型2.2 SOA架构 三、注意事项3.1 岗位职责3.2 项目背景3.3 理论部分讨论3.4 主体内容3.5 结论部分 四、范文4.1 开发模型主题反例正例 4.2 需求获取技术反例正例 4.3 系统测试反例正例 4.4反例正例 一、论文框架 二、相关素…

系统分析员论文12篇合集

系分论文1 企业人事信息系统的应用 【摘要】 本文讨论《企业人事信息系统》项目的需求分析方法与工具的选用。该系统的建设目标是帮助该企业管理好企业内部的人员和人员的活动&#xff0c;人事信息管理指的是企业员工从招聘面试到离职退休的全过程&#xff0c;涉及的主要活动…

系统分析师近几年论文走向

下面是整理的近几年的系统分析师考试论文题目

Java小游戏-俄罗斯方块

摘 要 随着时代的不断发展&#xff0c;个人电脑也在不断普及&#xff0c;一些有趣的桌面游戏已经成为人们在使用计算机进行工作或工作之余休闲娱乐的首选&#xff0c;从最开始的Windows系统自带的黑白棋、纸牌、扫雷等游戏开始&#xff0c;到现在目不暇接的各种游戏&#xff0…

Java版本实现俄罗斯方块小游戏

效果预览图 视频预览&#xff1a; 俄罗斯方块 代码部分 import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.Random;public class Block0011 extends JFrame implements KeyListener, ActionListener, MouseListener {// 记分int fenshu…

基于JAVA的俄罗斯方块游戏的设计与实现

目 录 1 引言 1.1 课题研究背景和意义 1.2 国内外现状分析 1.3 课题研究主要内容 1.4 论文组织结构 2 核心技术介绍 2.1 AWT技术介绍 2.2 eclipse编译器介绍 2.3 JAVA集合类技术简介 3 需求分析 3.1 游戏的设计模式 3.2 系统的设计目标 3.3 经济可行…

Java版俄罗斯方块

Java版俄罗斯方块 08年写的一个Java版俄罗斯方块程序 界面做的中规中矩&#xff0c;每种形状颜色都不相同 程序控制还可以&#xff0c;没什么大的Bug 消磨时间的时候可以Down下来玩玩 下载链接&#xff1a;http://download.csdn.net/user/zhaohuihua 菜单选项 也做了不少菜…

Java实现俄罗斯方块

结合网上的资料刚做完课程设计&#xff0c;具体代码如下&#xff1a; public class TetrisPanel extends JPanel{private final int[][] map new int[13][23];// map[列号][行号]。真正的方块区是:21行*10列。边框(2列&#xff0c;1行)// 方块的形状&#xff1a;// 第一维代表…

JAVA编写俄罗斯方块

JAVA编写俄罗斯方块 一.分析游戏界面 首先分析游戏界面&#xff0c;通过游戏界面&#xff0c;抽象出来几种类型。 1.Cell类型 2.Tetromino类型&#xff08;七种组合的父类&#xff09; 3.根据父类定义出七种T,O,I,J,L,S,Z子类型&#xff08;七种组合各自成一个类都继承于父类…

Java简易俄罗斯方块

目前学到Swing第二章&#xff0c;这两天没有学新知识&#xff0c;写了个俄罗斯方块。 写之前想不好怎么实现&#xff0c;找来别人的程序看了一下&#xff0c;再加上自己的想法&#xff0c;做了下面这个半成品&#xff0c;接下来可以加上各种菜单、按钮贴图等美化&#xff0c;都…

使用Java实现小游戏:俄罗斯方块

使用Java实现小游戏&#xff1a;俄罗斯方块 使用一个二维数组保存游戏的地图&#xff1a; // 游戏地图格子&#xff0c;每个格子保存一个方块&#xff0c;数组纪录方块的状态 private State map[][] new State[rows][columns];游戏前先将所有地图中的格子初始化为空&#xf…

JAVA实现经典游戏俄罗斯方块

本文代码来源于B站&#xff1a;尚学堂 博主也在此基础上有些改动&#xff0c;添加了一点提示标签和窗口 本文实现的功能有&#xff1a; 1、 初始化游戏窗口 2、初始化游戏的界面 3、初始化游戏的说明面板 4、随机生成下落方块 5、方块下落速度变化 6、判断方块是否可以下落 7、…

自己的第一个项目--俄罗斯方块(JAVA)

一点一点写出来的程序,想跟大家分享一下自己的心得,可能有错误,还请多多包涵~ Cell类: public class Cell 定义了本游戏最基本的元素:小方块(cell)的基本参数:行,列,小方块图片: private int row;//行数 private int col;//列数 private BufferedImage image;//图片 提供无…

Java俄罗斯方块 ---(一)游戏场景篇

相信俄罗斯方块大家都玩过&#xff0c;在这里就不多介绍规则了&#xff0c;用到的主要框架是Swing。 Java俄罗斯方块目录&#xff1a; Java俄罗斯方块 ---&#xff08;一&#xff09;游戏场景篇Java俄罗斯方块 ---&#xff08;二&#xff09;游戏操作与逻辑篇Java写俄罗斯方块…

java实现俄罗斯方块项目

导读:俄罗斯方块项目,基本功能包括:游戏主界面显示模块、方块及数据显示模块、方块移动控制模块、游戏界面颜色控制模块、游戏进度、等级控制模块等。本项目结构如下: (1)游戏主界面显示模块: 显示游戏和帮助两个菜单; 游戏使用功能键盘,得分 等级; (2)画布…

用JAVA写一个俄罗斯方块游戏tetrisGame

开拔 文章目录 开发环境前言一、先看一下游戏运行时的画面二、代码部分1.项目结构以及主程序入口以及下载路径下载路径代码1. Cell.java2. I.java3. J.java4. L.java5. O.java6. S.java7. T.java8. Tetris.java9. Tetromino.java10. Z.java 总结 开发环境 开发工具&#xff1a…

Java ——简易俄罗斯方块

一、将对象抽象为类 首先考虑俄罗斯方块游戏中含有哪些具体的对象&#xff0c;对象中含有哪些具体属性和方法&#xff0c;然后用代码来实现。 建立如下类&#xff1a; Cell类&#xff1a;代表最小的方格单位&#xff0c;构成7种图形的最基本图形。 含有row&#xff08;行号&…

【Java】俄罗斯方块小游戏(附源码)

俄罗斯方块小游戏 一、最终效果二、功能需求二、程序实现 一、最终效果 二、功能需求 1、 在二维平面里面用各种随机产生的方块堆积木&#xff0c;每满一行消去一行&#xff0c;当达到顶部时&#xff0c;游戏结束。 2、 通过方向键来控制方块转动&#xff0c;左移&#xff0c;…

Java实现俄罗斯方块附源码

Java实现俄罗斯方块 软件的开发过程&#xff1a; 1&#xff09; 搞清需求&#xff0c;就是软件的功能描述 俄罗斯方块的基本规则&#xff1a; 1、一个用于摆放小型正方形的平面虚拟场地&#xff0c;其标准大小&#xff1a; 行宽为10&#xff0c;列高为20&#xff0c;以每个小…