本篇主要讲解如何使用直接内存(堆外内存),并按照下面的步骤进行说明:
相关背景-->读写操作-->关键属性-->读写实践-->扩展-->参考说明希望对想使用直接内存的朋友,提供点快捷的参考。
数据类型下面这些,都是在使用DirectBuffer中必备的一些常识,暂作了解吧。
基本类型长度在Java中有很多的基本类型,比如:
byte,一个字节是8位bit,也就是1B
short,16位bit,也就是2B
int,32位bit,也就是4B
long, 64位bit,也就是8B
char,16位bit,也就是2B
float,32位bit,也就是4B
double,64位bit,也就是8B
不同的类型都会按照自己的位数来存储,并且可以自动进行转换提升。
byte、char、short都可以自动提升为int,如果操作数有long,就会自动提升为long,float和double也是如此。
由于一个数据类型可能有很多个字节组成的,那么它们是如何摆放的。这个是有讲究的:
大端:低地址位 存放 高有效字节
小端:低地址位 存放 低有效字节
举个例子,一个char是有两个字节组成的,这两个字节存储可能会显示成如下的模样,比如字符a:
低地址位 高地址位 大端; 00 96 小端: 96 00 String与new String的区别再说说"hello"和new String("hello")的区别:
如果是"hello",JVM会先去共享的字符串池中查找,有没有"hello"这个词,如果有直接返回它的引用;如果没有,就会创建这个对象,再返回。因此,"a"+"b"相当于存在3个对象,分别是"a"、"b"、"ab"。
而new String("hello"),则省去了查找的过程,直接就创建一个hello的对象,并且返回引用。
读写数据在直接内存中,通过allocateDirect(int byte_length)申请直接内存。这段内存可以理解为一段普通的基于Byte的数组,因此插入和读取都跟普通的数组差不多。
只不过提供了基于不同数据类型的插入方法,比如:
put(byte) 插入一个byte
put(byte[]) 插入一个byte数组
putChar(char) 插入字符
putInt(int) 插入Int
putLong(long) 插入long
等等....详细的使用方法,也可以参考下面的图片:
对应读取数据,跟写入差不多:
注意所有没有index参数的方法,都是按照当前position的位置进行操作的。
下面看看什么是position,还有什么其他的属性吧!
基本的属性值它有几个关键的指标:
mark-->position-->limit-->capacity另外,还有remaining=limit-position。
先说说他们的意思吧!
当前位置——positionposition是当前数组的指针,指示当前数据位置。举个例子:
ByteBuffer buffer = ByteBuffer.allocateDirect(1024); buffer.putChar('a'); System.out.println(buffer); buffer.putChar('c'); System.out.println(buffer); buffer.putInt(10); System.out.println(buffer);由于一个char是2个字节,一个Int是4个字节,因此position的位置分别是:
2,4,8注意,Position的位置是插入数据的当前位置,如果插入数据,就会自动后移。
也就是说,如果存储的是两个字节的数据,position的位置是在第三个字节上,下标就是2。
position可以通过position()获得,也可以通过position(int)设置。
//position(int)方法的源码 public final Buffer position(int newPosition) { if ((newPosition > limit) || (newPosition < 0)) throw new IllegalArgumentException(); position = newPosition; if (mark > position) mark = -1; return this; }注意:position的位置要比limit小,比mark大
空间容量——capacitycapacity是当前申请的直接内存的容量,它是申请后就不会改变的。
capacity则可以通过capacity()方法获得。
限制大小——limit我们可能想要改变这段直接内存的大小,因此可以通过一个叫做Limit的属性设置。
limit则可以通过limit()获得,通过limit(int)进行设置。