美文网首页
Netty之ByteBuf深入分析

Netty之ByteBuf深入分析

作者: huapro | 来源:发表于2019-06-12 20:02 被阅读0次

    netty中的PlatformDependent

    Netty之ByteBuf深入分析
    [TOC]
    分析思路
    内存与内存管理器的抽象
    ByteBuf 结构以及重要的API
    ByteBuf 数据结构

    • {@link ByteBuf} provides two pointer variables to support sequential
    • read and write operations - {@link #readerIndex() readerIndex} for a read
    • operation and {@link #writerIndex() writerIndex} for a write operation
    • respectively. The following diagram shows how a buffer is segmented into
    • three areas by the two pointers:
    • <pre>
    •  +-------------------+------------------+------------------+
      
    •  | discardable bytes |  readable bytes  |  writable bytes  |
      
    •  |                   |     (CONTENT)    |                  |
      
    •  +-------------------+------------------+------------------+
      
    •  |                   |                  |                  |
      
    •  0      <=      readerIndex   <=   writerIndex    <=    capacity
      
    • </pre>
    • <h4>Readable bytes (the actual content)</h4>

    read ,write set 方法
    mark 和 reset方法
    ByteBuf 分类
    Pooled 和 Unpooled
    Pooled池化内存分配每次从预先分配好的一块内存取一段连续内存封装成ByteBuf提供给应用程序,
    Unpooled非池化每次进行内存分配的时候调用系统API向操作系统申请一块内存
    Unsafe 和 非Unsafe
    Unsafe直接获取ByteBuf在JVM内存地址调用JDK的Unsafe进行读写操作,通过ByteBuf分配内存首地址和当前指针基于内存偏移地址获取值,
    非Unsafe不依赖JDK的Unsafe对象,通过内存数组和索引获取值
    Heap和Direct
    Heap在堆上进行内存分配,分配内存需要被GC管理,无需手动释放内存,依赖底层byte数组,
    Direct调用JDK的API进行内存分配,分配内存不受JVM控制最终不会参与GC过程,需要手动释放内存避免造成内存无法释放,依赖DirectByteBuffer对象内存
    内存分配器ByteBufAllocator分析
    ByteBufAllocator功能
    buffer()方法分配内存是否为Direct/Heap内存依赖具体实现,
    ioBuffer()方法分配内存更希望是适合IO的Direct Buffer,directBuffer()/headBuffer()方法堆内/堆外进行内存分配,compositeBuffer()方法分配将两个ByteBuf合并变成CompositeByteBuf
    AbstractByteBufAllocator
    buffer()方法分配Buffer依赖实现分配内存,调用directBuffer()/heapBuffer()方法分配默认Buffer容量和最大扩充容量的ByteBuf,newDirectBuffer()/newHeapBuffer()方法分配Pooled/Unpooled依赖底层实现
    ByteBufAllocator两个子类
    PooledByteBufAllocator从预先分配好的内存取一段内存,
    UnpooledByteBufAllocator调用系统API分配内存,调用hasUnsafe()方法获取Unsafe决定分配Unsafe/非Unsafe
    UnpooledByteBufAllocator分析
    heap内存的分配
    newHeapBuffer()方法通过hasUnsafe()方法判断是否有Unsafe
    传递initialCapacity容量Byte数组参数setArray()方法设置array以及setIndex()方法设置读/写指针
    创建UnpooledUnsafeHeapByteBuf/UnpooledHeapByteBuf,
    _get***()方法通过Unsafe方式返回数组对象偏移量[BYTE_ARRAY_BASE_OFFSET+index]对应的byte/数组索引方式返回array数组index位置byte
    direct内存的分配
    newDirectBuffer()方法通过hasUnsafe()方法判断是否有Unsafe
    调用allocateDirect(initialCapacity)创建DirectByteBuffer
    使用setByteBuffer()方法设置buffer[UnpooledUnsafeDirectByteBuf
    使用directBufferAddress()方法获取buffer内存地址设置memoryAddress

    创建UnpooledUnsafeDirectByteBuf/UnpooledDirectByteBuf,
    _get***()方法通过addr()方法memoryAdress+index计算内存地址
    Unsafe获取对应这块内存的byte/ByteBuffer获取buffer index位置对应的byte
    不同规格大小和不同类别的内存的分配策略
    内存规格介绍
    0 <-tiny->512B<-small->8K<-normal->16M<-huge->
    |______________________| |
    SubPage Page Chunk

    16M作为分界点对应的Chunk,
    所有的内存申请以Chunk为单位向操作系统申请,
    内存分配在Chunk里面执行相应操作,
    16M Chunk按照Page进行切分为2048个Page,8K Page按照SubPage切分
    内存的回收过程

    常见问题
    Netty 的内存的类别有哪些?
    堆内内存/堆外内存
    堆内[基于2048byte字节内存数组分配]
    堆外[基于JDK的DirectByteBuffer内存分配]
    Unsafe/非Unsafe
    Unsafe[通过JDK的Unsafe对象基于物理内存地址进行数据读写]
    非Unsafe[调用JDK的API进行读写]
    UnPooled/Pooled
    UnPooled[每次分配内存申请内存]
    Pooled[预先分配好一整块内存,分配的时候用一定算法从一整块内存取出一块连续内存]
    如何减少多线程内存分配之间的竞争关系?
    PooledByteBufAllocator内存分配器结构维护Arena数组,所有的内存分配都在Arena上进行,
    通过PoolThreadCache对象将线程和Arena进行一一绑定, 默认情况一个Nio线程管理一个Arena实现多线程内存分配相互不受影响减少多线程内存分配之间的竞争
    不同大小的内存是如何进行分配的?
    Page级别的内存分配通过完全二叉树的标记查找某一段连续内存,
    Page级别以下的内存分配首先查找到Page然后把此Page按照SubPage大小进行划分最后通过位图的方式进行内存分配
    不同大小的内存是如何进行分配的?2
    Netty一次向系统申请16M的连续内存空间,这块内存通过PoolChunk对象包装,进一步的把这16M内存分成了2048个页(pageSize=8k)。页作为Netty内存管理的最基本的单位 ,所有的内存分配首先必须申请一块空闲页。
    对于小内存(小于4096)的分配还会将Page细化成更小的单位Subpage。Subpage按大小分有两大类,36种情况:Tiny:小于512的情况,最小空间为16,对齐大小为16,区间为[16,512),所以共有32种情况。Small:大于等于512的情况,总共有四种,512,1024,2048,4096。

    作者:石家志远
    链接:https://www.jianshu.com/p/2498db9c91fe
    来源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

    相关文章

      网友评论

          本文标题:Netty之ByteBuf深入分析

          本文链接:https://www.haomeiwen.com/subject/vmurfctx.html