bytebuffer

Direct vs non-direct ByteBuffer

青春壹個敷衍的年華 提交于 2020-03-11 10:25:17
先解释一下两者的区别: Non-direct ByteBuffer 内存是分配在堆上的,直接由 Java 虚拟机负责垃圾收集,你可以把它想象成一个字节数组的包装类,如下伪码所示: HeapByteBuffer extends ByteBuffer { byte[] content; int position, limit, capacity; ...... } 而 Direct ByteBuffer 是通过 JNI 在 Java 虚拟机外的内存中分配了一块(所以即使在运行时通过 -Xmx 指定了 Java 虚拟机的最大堆内存,还是 可能 实例化超出该大小的 Direct ByteBuffer ),该内存块并不直接由 Java 虚拟机负责垃圾收集,但是在 Direct ByteBuffer 包装类被回收时,会通过 Java Reference 机制来释放该内存块。如下伪码所示: DirectByteBuffer extends ByteBuffer { long address; int position, limit, capacity; protected void finalize() throws Throwable{ // 释放内存块,该段代码仅仅用于演示,真正的 Direct ByteBuffer 并不是通过 finalize 来释放的 releaseAddress();

ByteBuffer的实验

て烟熏妆下的殇ゞ 提交于 2020-03-11 10:17:48
//代码参考 https://blog.csdn.net/coding_1994/article/details/87902828 ByteBuffer buff = ByteBuffer.allocate(1024); String str = "helloWorld"; buff.put(str.getBytes()); System.out.println(new String(buff.array())); System.out.println("position:" + buff.position() + "\t limit:" + buff.limit() + "\t capacity:" + buff.capacity()); // 读取两个字节byte[] abytes = new byte[1]; byte[] abytes = new byte[1]; buff.get(abytes);//其实是byte 0值 System.out.println("get one byte to string:" + new String(abytes)); // Reads the byte at this buffer's current position, and then increments // the position. buff.get();/

JVM内存结构学习:三、堆外内存

微笑、不失礼 提交于 2020-03-10 10:56:40
一、什么是堆外内存 1、堆内内存(on-heap memory)回顾 堆外内存和堆内内存是相对的二个概念,其中堆内内存是我们平常工作中接触比较多的,我们在jvm参数中只要使用-Xms,-Xmx等参数就可以设置堆的大小和最大值,理解jvm的堆还需要知道下面这个公式: 堆内内存 = 新生代+老年代+持久代 如下面的图所示: Paste_Image.png 在使用堆内内存(on-heap memory)的时候,完全遵守JVM虚拟机的内存管理机制,采用垃圾回收器(GC)统一进行内存管理,GC会在某些特定的时间点进行一次彻底回收,也就是Full GC,GC会对所有分配的堆内内存进行扫描,在这个过程中会对JAVA应用程序的性能造成一定影响,还可能会产生Stop The World。 2、堆外内存(off-heap memory)介绍 和堆内内存相对应,堆外内存就是把内存对象分配在Java虚拟机的堆以外的内存,这些内存直接受操作系统管理(而不是虚拟机),这样做的结果就是能够在一定程度上减少垃圾回收对应用程序造成的影响。 作为JAVA开发者我们经常用java.nio.DirectByteBuffer对象进行堆外内存的管理和使用,它会在对象创建的时候就分配堆外内存。 DirectByteBuffer类是在Java Heap外分配内存,对堆外内存的申请主要是通过成员变量unsafe来操作

NIO中Buffer缓冲区的实现

不问归期 提交于 2020-03-03 23:28:10
Buffer 缓冲区 Java的NIO中Buffer至关重要:buffer是读写的中介,主要和NIO的通道交互。数据是通过通道读入缓冲区和从缓冲区写入通道的。 其实缓冲区buffer的本质就是一块可以读写的内存块。这块内存块被包装成NIO的Buffer对象,并提供了一组方法方便读写。 3.1 Buffer的基本用法: 使用Buffer读写数据一般是下面步骤: 1. 写入数据到Buffer 2. 调用flip()方法:Buffer从写模式切换到读模式。 3. 从buffer读取数据 4. 调用clear()方法或则compact()方法。 当向buffer写入数据时,buffer会记录下写了多少数据。一旦要读取数据,需要通过flip()方法将Buffer从写模式切换到读模式。在读模式下,可以读取之前写入到buffer的所有数据。 一旦读完了所有的数据,就需要清空缓冲区,让它可以再次被写入。有两种方式能清空缓冲区:调用clear()或compact()方法。clear()方法会清空整个缓冲区。compact()方法只会清除已经读过的数据。任何未读的数据都被移到缓冲区的起始处,新写入的数据将放到缓冲区未读数据的后面。 下面是一个简单的示例: 1 RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw")

ByteBuf和Channel和Pipeline

无人久伴 提交于 2020-03-01 22:13:02
BytetBuf ByteBuf就是JDK nio中Buffer的新轮子 buffer 的主要目的进行流量整形,把突发的大数量较小规模的 I/O 整理成平稳的小数量较大规模的 I/O,以 减少响应次数 ByteBuffer: 长度固定,一旦分配完成,它的容量不能动态扩展和收缩,当需要编码的POJO对象大于ByteBuffer的容量时,会发生索引越界异常; ByteBuffer只有一个标识位控的指针position,读写的时候需要手工调用flip()和rewind()等,使用者必须小心谨慎地处理这些API,否则很容易导致程序处理失败; ByteBuffer的API功能有限,一些高级和实用的特性它不支持,需要使用者自己编程实现。 需要的话,可以自定义buffer类型; 通过组合buffer类型,可实现透明的zero-copy; 提供动态的buffer类型,如StringBuffer一样,容量是按需扩展; 如果c<t,则n从阈值t(4MB)开始,以每次增加2倍的方式扩容,直到双倍后的大小小于c; 如果c>t,则n=c/t*t+t 无需调用flip()方法;方法反转(讲Buffer从读模式变成写模式) 常常比 ByteBuffer (JDK的)快 使用了读写两个指针,分别记录读写的位置,复杂操作更简单 堆内存和直接内存

netty—入门(二)—NIO(1)

非 Y 不嫁゛ 提交于 2020-03-01 12:06:38
NIO入门 1、理论知识 一个线程从某个通道(一个线程可以管理多个通道)发送请求或者读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可以使用,那么就什么都不会获取, 而不是保持线程阻塞 ,所以直至数据变得可以读取之前,该线程就可以继续做其他的事情。 2、案例 完整代码: public class BasicBuffer { public static void main ( String [ ] args ) { //创建一个buffer 大小为5 5个int(不同的类型对应不同的buffer,int char 等,不同的类型对应不同的等级,不同的数据放在不同的buffer里面,提高效率) IntBuffer intBuffer = IntBuffer . allocate ( 5 ) ; //向bufffer中纺织数据 for ( int i = 0 ; i < intBuffer . capacity ( ) ; i ++ ) { intBuffer . put ( i * 2 ) ; } //将bufer转换,读写转换(!!!!) intBuffer . flip ( ) ; while ( intBuffer . hasRemaining ( ) ) { //每次get之后就往后移动一次 System . out . println ( intBuffer .

Java NIO基础知识整理(一)

社会主义新天地 提交于 2020-03-01 00:28:18
NIO 特性 1、 为原始类提供缓存支持; 2 、字符集编码解码解决方案; 3 、 Channel :一个新的原始 I/O 抽象; 4 、支持锁和内存映射文件的文件访问接口; 5 、提供多路非阻塞式( non-bloking )的高伸缩性网络 I/O 。 Buffer 在基本 I/O 操作中所有的操作都是直接以流的形式完成的,而在 NIO 中所有的操作都要使用到缓冲区处理,且所有的读写操作都是通过缓冲区完成的。缓冲区( Buffer )是一个线性的、有序的数据集,只能容纳某种特定的数据类型。 一个 Buffer 有以下几个属性: 容量( capacity ) :缓冲区能包含的元素的最大数目。 限制( limit ) :第一个无法被写入或读取的元素坐标。 坐标( position ) :下一个要写入或读取的元素的坐标。 更多 Buffer 的属性和方法参考 http://download.oracle.com/javase/6/docs/api/ 。 另外, http://www.linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ314_027.htm 上面有一个各种类型的 Buffer 和 byte[] 之间相互转换的模型图,挺有帮助的。 图 1 Buffer 内部结构 看一下一个简单的示例

java-nio

时光怂恿深爱的人放手 提交于 2020-02-29 11:18:16
javanio可以替换传统的io,对于java 的nio理解,可以联想到io。但是他们也有不一样的地方。 1.传统io和nio区别: 2. Buffer 中的重要概念: Ø 容量 (capacity) : 表示 Buffer 最大数据容量,缓冲区容量不能为负,并且创建后不能更改。 缓冲区其实就是数据组,因为是数组,所以数据容量一旦固定就不能修改了。 Ø 限制 (limit) : 第一个不应该读取或写入的数据的索引,即位于 limit 后的数据不可读写。缓冲区的限制不能为负,并且不能大于其容量。 Ø 位置 (position) : 下一个要读取或写入的数据的索引。缓冲区的位置不能为负,并且不能大于其限制 Ø 标记 (mark) 与重置 (reset) : 标记是一个索引,通过 Buffer 中的 mark() 方法指定 Buffer 中一个特定的 position ,之后可以通过调用 reset() 方法恢复到这个 position 。 标记、 位置、 限制、 容量遵守以下不变式: 0 <= mark <= position <= limit <= capacity 注意: mark 初始化为 -1 ,表示没有标记过 3.来段代码理解一下 package com.nio.nio; import java.nio.ByteBuffer; import org.junit.Test; /

OOM以及垃圾收集器

点点圈 提交于 2020-02-26 10:06:15
1.常见的几种OOM? ①java.lang.StackOverflowError②java.lang.OutOfMemoryError:Java heap space③java.lang.OutOfMemoryError:GC overhead limit exceeded④java.lang.OutOfMemoryError:Direct buffer memory⑤java.lang.OutOfMemoryError:unable to create new native thread⑥java.lang.OutOfMemoryError:Metaspace /** * 描述:GC overhead Limit * jvm参数配置演示:-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+MaxDirectMemorySize=5m * GC回收时间过长会抛出OutOfMemroyError,过长的定义是,超过98%的时间来做GC并且只回收了不到2%的堆内存 * 连续多次GC都只是回收了不到2%的极端情况下才会抛出,假如不抛出GC Overhead limit错误会发生什么呢? * CPU使用率一直是100%,而GC没有任何成功 * * @author xinjiao.yu@marketin.cn * @create 2020/2/24 21:41

Java NIO系列(二) - Buffer

心不动则不痛 提交于 2020-02-25 07:25:01
前言 在 Java NIO 中, 缓冲区 用来 临时 存储数据,可以理解为是 I/O 操作中数据暂存的中转站。 缓冲区 直接为 通道 ( Channel )服务,数据是从 通道 读入 缓冲区 ,从 缓冲区 写入到 通道 中的。 缓冲区 本质上是一块可以 写入数据 ,然后可以从中 读取数据 的内存。这块内存被包装成 NIO Buffer 对象,并提供了一组方法,用来方便的访问 这块内存 。 正文 Buffer的类型 Java NIO 提供以下几种 Buffer 类型: ByteBuffer MappedByteBuffer ShortBuffer LongBuffer FloatBuffer CharBuffer IntBuffer DoubleBuffer 这些 Buffer 类型代表了 Java 中7种基本数据类型。换句话说,就是可以通过 byte 、 char 、 short 、 int 、 long 、 float 或 double 类型来操作 缓冲区 中的数据。 Buffer的基本用法 使用 Buffer 读写数据一般遵循以下四个步骤: 写入数据到 Buffer 中; 调用 Buffer 的 flip() 方法; 从 Buffer 中读取数据; 调用 clear() 方法或者 compact() 方法。 当向 Buffer 写入数据时, Buffer 会记录下写了多少数据