1.创建DirectByteBuffer

  Direct ByteBuffer是通过JNI在Java虚拟机外的内存中分配了一块(所以即使在运行时通过-Xmx指定了Java虚拟机的最大堆内存,还是可能实例化超出该大小的Direct ByteBuffer),该内存块并不直接由Java虚拟机负责垃圾收集.

使用allocateDirect()静态方法创建对象分配内存

  ByteBuffer buffer=ByteBuffer.allocateDirect(256);

 1 /**
2 * Allocates a new direct byte buffer.
3 *
4 * <p> The new buffer's position will be zero, its limit will be its
5 * capacity, its mark will be undefined, and each of its elements will be
6 * initialized to zero. Whether or not it has a
7 * {@link #hasArray </code>backing array<code>} is unspecified.
8 *
9 * @param capacity The new buffer's capacity, in bytes
10 * @return The new byte buffer
11 * @throws IllegalArgumentException If the <tt>capacity</tt> is a negative integer
12 */
13 public static ByteBuffer allocateDirect(int capacity) {
14 if (capacity < 0) {
15 throw new IllegalArgumentException("capacity < 0: " + capacity);
16 }
17
18 DirectByteBuffer.MemoryRef memoryRef = new DirectByteBuffer.MemoryRef(capacity);
19 return new DirectByteBuffer(capacity, memoryRef);
20 }
21 //
22 public MemoryRef(int capacity) {
23 VMRuntime runtime = VMRuntime.getRuntime();
24 buffer = (byte[]) runtime.newNonMovableArray(byte.class, capacity + 7);
25 allocatedAddress = runtime.addressOf(buffer);
26 // Offset is set to handle the alignment: http://b/16449607
27 offset = (int) (((allocatedAddress + 7) & ~(long) 7) - allocatedAddress);
28 isAccessible = true;
29 isFreed = false;
30 }

  以上方法将创建一个容量为256字节的DirectByteBuffer,如果发现创建的缓冲区容量太小,唯一的选择就是重新创建一个大小合适的缓冲区.

DirectByteBuffer主要应用在android数据传递过程.减少数据与JNI数据拷贝转换操作

DirectByteBuffer.putInt(value);
下面分析一下当执行putInt后,DirectByteBuffer都执行了什么操作
 1     //计算写数据的位置
2 @Override
3 public final ByteBuffer putInt(int x) {
4 if (!memoryRef.isAccessible) {
5 throw new IllegalStateException("buffer is inaccessible");
6 }
7 if (isReadOnly) {
8 throw new ReadOnlyBufferException();
9 }
10 putInt(ix(nextPutIndex(SizeOf.INT)), x);
11 return this;
12 }
13 //调用Memory来完成Int数据存储
14 private ByteBuffer putInt(long a, int x) {
15 Memory.pokeInt(a, x, !nativeByteOrder);
16 return this;
17 }
18
19 private long ix(int i) {
20 return address + i;
21 }
22

再往下看Memory做了什么

1 public static void pokeInt(long address, int value, boolean swap) {
2 if (swap) {
3 value = Integer.reverseBytes(value);
4 }
5 pokeIntNative(address, value);
6 }
7 //因为最后执行到JNI层.这块就不涉及到字节序的问题
8 private static native void pokeIntNative(long address, int value);

当执行 DirectByteBuffer.getInt();都执行了哪些操作

 1 public int getInt() {
2 if (!memoryRef.isAccessible) {
3 throw new IllegalStateException("buffer is inaccessible");
4 }
5 return getInt(ix(nextGetIndex(SizeOf.INT)));
6 }
7
8 //最后执行Memory 的JNI方法
9 private int getInt(long a) {
10 return Memory.peekInt(a, !nativeByteOrder);
11 }
12 //Memory 执行的操作
13 public static int peekInt(long address, boolean swap) {
14 int result = peekIntNative(address);
15 if (swap) {
16 result = Integer.reverseBytes(result);
17 }
18 return result;
19 }
20 private static native int peekIntNative(long address);

所以得出结论就本身在Java中引入DirectByteBuffer并不会提高性能

DirectByteBuffer实现原理分析的更多相关文章

  1. Java Reference核心原理分析

    本文转载自Java Reference核心原理分析 导语 带着问题,看源码针对性会更强一点.印象会更深刻.并且效果也会更好.所以我先卖个关子,提两个问题(没准下次跳槽时就被问到). 我们可以用Byte ...

  2. Handler系列之原理分析

    上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信 ...

  3. Java NIO使用及原理分析(1-4)(转)

    转载的原文章也找不到!从以下博客中找到http://blog.csdn.net/wuxianglong/article/details/6604817 转载自:李会军•宁静致远 最近由于工作关系要做一 ...

  4. 原子类java.util.concurrent.atomic.*原理分析

    原子类java.util.concurrent.atomic.*原理分析 在并发编程下,原子操作类的应用可以说是无处不在的.为解决线程安全的读写提供了很大的便利. 原子类保证原子的两个关键的点就是:可 ...

  5. Android中Input型输入设备驱动原理分析(一)

    转自:http://blog.csdn.net/eilianlau/article/details/6969361 话说Android中Event输入设备驱动原理分析还不如说Linux输入子系统呢,反 ...

  6. 转载:AbstractQueuedSynchronizer的介绍和原理分析

    简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...

  7. Camel运行原理分析

    Camel运行原理分析 以一个简单的例子说明一下camel的运行原理,例子本身很简单,目的就是将一个目录下的文件搬运到另一个文件夹,处理器只是将文件(限于文本文件)的内容打印到控制台,首先代码如下: ...

  8. NOR Flash擦写和原理分析

    NOR Flash擦写和原理分析 1. NOR FLASH 的简单介绍 NOR FLASH 是很常见的一种存储芯片,数据掉电不会丢失.NOR FLASH支持Execute On Chip,即程序可以直 ...

  9. 使用AsyncTask异步更新UI界面及原理分析

    概述: AsyncTask是在Android SDK 1.5之后推出的一个方便编写后台线程与UI线程交互的辅助类.AsyncTask的内部实现是一个线程池,所有提交的异步任务都会在这个线程池中的工作线 ...

随机推荐

  1. Atcoder Grand Contest 015 F - Kenus the Ancient Greek(找性质+乱搞)

    洛谷题面传送门 & Atcoder 题面传送门 一道难度 Au 的 AGC F,虽然看过题解之后感觉并不复杂,但放在现场确实挺有挑战性的. 首先第一问很简单,只要每次尽量让"辗转相除 ...

  2. Codeforces 1542E2 - Abnormal Permutation Pairs (hard version)(DP)

    upd on 2021.7.7:修了个 typo Codeforces 题目传送门 & 洛谷题目传送门 首先考虑怎样处理"字典序小"这个问题,按照字典序比大小的套路,我们可 ...

  3. kubernetes部署 etcd 集群

    本文档介绍部署一个三节点高可用 etcd 集群的步骤: etcd 集群各节点的名称和 IP 如下: kube-node0:192.168.111.10kube-node1:192.168.111.11 ...

  4. cmd到指定目录并执行命令 mysql到bin目录并执行命令 cmd bat进入指定文件夹中并执行命令

    其实就一条命令:(保存为bat格式,注意:有两个and希腊字母 && )cmd /k "cd /d Your ProjectPath&&Your CMD co ...

  5. 学习java 7.13

    学习内容: 一个汉字存储:如果是GBK编码,占用2个字节:如果是UTF-8编码,占用3个字节 汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数 字符流=字节流+编码表 采用何种规则编码,就要 ...

  6. Erda 系列 Meetup「成都站」携手SOFAStack 和你聊聊云原生基础设施建设那点事儿

    技术控快上车啦秋天的第一场活动一起来收获技术干货吧! 主题: 云原生基础设施建设的现在及未来时间: 2021 年 9 月 11 日 (周六) 13:30-17:00活动地点: 四川省成都市蚂蚁 C 空 ...

  7. 大数据学习day25------spark08-----1. 读取数据库的形式创建DataFrame 2. Parquet格式的数据源 3. Orc格式的数据源 4.spark_sql整合hive 5.在IDEA中编写spark程序(用来操作hive) 6. SQL风格和DSL风格以及RDD的形式计算连续登陆三天的用户

    1. 读取数据库的形式创建DataFrame DataFrameFromJDBC object DataFrameFromJDBC { def main(args: Array[String]): U ...

  8. Linux定时任务crontable简介

    Linux下定时执行任务的方法:Linux之crond 服务介绍:https://www.cnblogs.com/liang-io/p/9596294.html http://www.mamicode ...

  9. zabbix之邮件报警

    创建媒介类型 如果用QQ邮箱的话,先设置一下授权码 为用户设置报警 创建一个用户 配置动作 测试

  10. vue引入d3

    单页面使用 cnpm install d3 --save-dev 指定版本安装 cnpm install d3@6.3.1 -S <script> import * as d3 from ...