感悟优化——Netty对JDK缓冲区的内存池零拷贝改造

NIO中缓冲区是数据传输的基础,JDK通过ByteBuffer实现,Netty框架中并未采用JDK原生的ByteBuffer,而是构造了ByteBuf。

ByteBuf对ByteBuffer做了大量的优化,比如说内存池,零拷贝,引用计数(不依赖GC),本文主要是分析这些优化,学习这些优化思想,学以致用,在实际工程中,借鉴这些优化方案和思想。

 

直接内存和堆内存

首先先讲一下这里面需要用的基础知识,在JVM中 内存可分为两大块,一个是堆内存,一个是直接内存。这里简单介绍一下

堆内存:

堆内存是Jvm所管理的内存,相比方法区,栈内存,堆内存是最大的一块。所有的对象实例实例以及数组都要在堆上分配。

Java的垃圾收集器是可以在堆上回收垃圾。

直接内存:

JVM使用Native函数在堆外分配内存,之后通过Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。直接内存不会受到Java堆的限制,只受本机内存影响。

Java的GC只会在老年区满了触发Full GC时,才会去顺便清理直接内存的废弃对象。

JDK原生缓冲区ByteBuffer

在NIO中,所有数据都是用缓冲区处理的。读写数据,都是在缓冲区中进行的。缓存区实质是是一个数组,通常使用字节缓冲区——ByteBuffer。

属性:

属性

 

说明

 

capacity

 

缓冲区的大小,一旦申请将不能改变

 

position

 

位置索引,表示读模式或者写模式数据的位置,读模式和写模式切换的时候position会被重置为0positon最大可谓capacity-1

 

limit

 

在写模式下,Bufferlimit表示你最多能往Buffer里写多少数据。读模式下,limit等于buffercapacity

 

mark

 

标记,指一个备忘位置,调用mark()来设定mark=position,调用reset()来设定postion=mark,标记未设定前是未定义的.

 

使用方式:

ByteBuffer可以申请两种方式的内存,分别为堆内存和直接内存,首先看申请堆内存。

// 申请堆内存 ByteBuffer HeapbyteBuffer = ByteBuffer.allocate(1024);

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpszdg.html