netty并发量一般多少_netty内存池原理

说在前面前期回顾sharding-jdbc源码解析更新完毕spring源码解析 更新完毕spring-mvc源码解析 更新完毕spring-tx源码解析 更新完毕spring-boot源码解析 更新完毕rocketmq源码解析 更新完毕dubbbo源码解析 更新完毕netty源码解析 更新完毕spring源码架构更新完毕spring-mvc源码架构更新完毕spring-boot源码架构...
摘要由CSDN通过智能技术生成

说在前面

前期回顾

sharding-jdbc源码解析 更新完毕

spring源码解析 更新完毕

spring-mvc源码解析 更新完毕

spring-tx源码解析 更新完毕

spring-boot源码解析 更新完毕

rocketmq源码解析 更新完毕

dubbbo源码解析 更新完毕

netty源码解析 更新完毕

spring源码架构更新完毕

spring-mvc源码架构更新完毕

spring-boot源码架构更新完毕

github https://github.com/tianheframe

sharding-jdbc源码解析 更新完毕

rocketmq源码解析 更新完毕

seata 源码解析 更新完毕

dubbo 源码解析 更新完毕

netty 源码解析 更新完毕

源码解析

netty的精华之处就是内存池的设计和reactor线程模型设计,本次主要介绍下内存池的原理,内存池的好处是可以重复使用堆内存区域,降低内存申请的频率同时也降低了JVM GC的频率,netty一般用来做设计海量的分布式场景下的底层网络通讯技术模块实现,所以内存池就显得尤为重要了,进一步提高系统吞吐量

我们还是从源码的维度去解析,io.netty.buffer.Unpooled#buffer(int)方法创建一个堆缓冲区

public static ByteBuf buffer(int initialCapacity) {
        return ALLOC.heapBuffer(initialCapacity);}

io.netty.buffer.AbstractByteBufAllocator#heapBuffer(int, int)

@Override    public ByteBuf heapBuffer(int initialCapacity, int maxCapacity) {
            if (initialCapacity == 0 && maxCapacity == 0) {
                return emptyBuf;        }//        验证参数合法性,最大的堆缓冲区容量是int最大值字节        validate(initialCapacity, maxCapacity);        return newHeapBuffer(initialCapacity, maxCapacity);    }

基于内存池创建堆缓冲区这个方法io.netty.buffer.PooledByteBufAllocator#newHeapBuffer

@Override    protected ByteBuf newHeapBuffer(int initialCapacity, int maxCapacity) {
    //        先从本地缓存内存中取        PoolThreadCache cache = threadCache.get();//        获取堆区域        PoolArena<byte[]> heapArena = cache.heapArena;        final ByteBuf buf;        if (heapArena != null) {
    //            从这块堆区域中分配缓冲区            buf = heapArena.allocate(cache, initialCapacity, maxCapacity);//            否则就不用内存池直接分配内存        } else {
                buf = PlatformDependent.hasUnsafe() ?                    new UnpooledUnsafeHeapByteBuf(this, initialCapacity, maxCapacity) :                    new UnpooledHeapByteBuf(this, initialCapacity, maxCapacity);        }//        检测是否有内存泄漏        return toLeakAwareBuffer(buf);    }

基于内存池区域分配缓冲区io.netty.buffer.PoolArena#allocate(io.netty.buffer.PoolThreadCache, int, int)

PooledByteBufallocate(PoolThreadCache cache, int reqCapacity, int maxCapacity) {
    //        创建基于内存池的byteBuf        PooledByteBuf buf = newByteBuf(maxCapacity);//        分配内存        allocate(cache, buf, reqCapacity);        return buf;    }

基于内存池创建byteBuf有两种方式,堆内存、直接内存

a3823b63f9d44beba520b257b93a4342.png

基于内存池分配堆内存io.netty.buffer.PoolArena.HeapArena#newByteBuf

@Overrideprotected PooledByteBuf<byte[]> newByteBuf(int maxCapacity) {
        return HAS_UNSAFE ? PooledUnsafeHeapByteBuf.newUnsafeInstance(maxCapacity)            : PooledHeapByteBuf.newInstance(maxCapacity);}

io.netty.buffer.PooledHeapByteBuf#newInstance创建PooledHeapByteBuf对象

static PooledHeapByteBuf newInstance(int maxCapacity) {
    //        从对象回收器中回收一个对象        PooledHeapByteBuf buf = RECYCLER.get();        buf.reuse(maxCapacity);        return buf;    }

io.netty.buffer.PooledByteBuf#reuse重写设置一些参数

final void reuse(int maxCapacity) {
            maxCapacity(maxCapacity);//        设置引用计数,这里是线程安全的        setRefCnt(1);//        设置读写索引        setIndex0(0, 0);        discardMarks();    }

通过上面源码跟踪发现用内存池分配缓冲区有三个主要的点

1、一个是从本地线程缓冲池中找到poolThreadCache,再从poolThreadCache中找到heapArena,如果有存在headArena就是开始分配内存

2、分配内存的时候先从对象回收器RECYCLER中回收一个对象PooledByteBuf,类似一个对象池的作用,在进行分配内存,对象可以循环利用,提供内存分配效率和JVM gc效率,这个对象回收器是基于引用计数方式实现的

3、分配内存

4、0 copy

PoolThreadCache

充当分配线程的缓存,这里的设计可以提升对象内存分配的效率,假设你想在给对象创建时分配对象的时候怎么提升对象分配的效率呢,就是快速拿到可用内存,那如果是高并发情况下,因为netty就是为分布式、高并发场景而设计的,所以高并发场景下给对象分配内存空间是一种常态,那么这种场景下应该怎么提升对象内存的分配效率呢,那我想到的就是减少多线程操作一块内存区域的锁争用,还有就是在标记那一块内存未使用,那一块已经使用了在维护这个内存使用记录的时候采用cas操作,再用的话就是给每个线程预先分配一块内存,在每个对象需要进行对象创建分配内存的时候先从本地线程缓存中获取内存,获取不到在从堆中申请内存,这种方式可以一定程度上减少多线程之间操作一块内存的锁争用,也能很好的提升对象内存分配的并发度,很大程度上能提升对象内存分配的性能,PoolThreadCache正是基于这种方式实现的。

那接下来我们跟着源码看下netty是怎么设计线程本地缓存的,它是基于PoolThreadLocalCache实现的,PoolThreadLocalCache集成了FastThreadLocal,FastThreadLocal是netty扩展了自己的threadLocal,为什么名字是Fast开头呢,从FastThreadLocal访问时可以产生很好的性能,底层是用数组实现的,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值