Netty源码分析---PooledByteBufAllocator 源码深度解析

Netty源码分析:PooledByteBufAllocator Netty源码分析:PooledByteBufAllocator无论是我们使用语句ByteBuf byteBuf = Unpooled.buffer(256);来分配buf,还是使用如下的语句来分配Buf: PooledByteBufAllocator allocator = new PooledByteBufAllocator(false); ByteBuf byte 阅读详情

PooledByteBufAllocator 源码深度解析

一、类的定位和继承关系

public class PooledByteBufAllocator extends AbstractByteBufAllocator 
    implements ByteBufAllocatorMetricProvider

继承关系:

  • AbstractByteBufAllocator:提供基础的分配逻辑
  • ByteBufAllocatorMetricProvider:提供监控指标接口

作用:

  • Netty 内存池的总管理者
  • 管理所有的 Arena(内存区域)
  • 管理所有的 ThreadCache(线程本地缓存)
  • 提供统一的内存分配入口

二、静态常量(默认配置)

2.1 核心配置常量

// Arena 数量
private static final int DEFAULT_NUM_HEAP_ARENA;      // 堆内存 Arena 数量
private static final int DEFAULT_NUM_DIRECT_ARENA;    // 直接内存 Arena 数量

// Chunk 配置
private static final int DEFAULT_PAGE_SIZE;           // Page 大小,默认 8KB
private static final int DEFAULT_MAX_ORDER;           // 最大深度,默认 11
// ChunkSize = 8192 << 11 = 16 MiB

// ThreadCache 缓存大小
private static final int DEFAULT_TINY_CACHE_SIZE;     // Tiny 缓存,默认 512
private static final int DEFAULT_SMALL_CACHE_SIZE;    // Small 缓存,默认 256
private static final int DEFAULT_NORMAL_CACHE_SIZE;   // Normal 缓存,默认 64

// 其他配置
private static final int DEFAULT_MAX_CACHED_BUFFER_CAPACITY;  // 最大缓存容量,32KB
private static final int DEFAULT_CACHE_TRIM_INTERVAL;         // 缓存清理间隔,8192 次
private static final long DEFAULT_CACHE_TRIM_INTERVAL_MILLIS; // 缓存清理时间间隔
private static final boolean DEFAULT_USE_CACHE_FOR_ALL_THREADS; // 是否所有线程使用缓存

2.2 边界值常量

private static final int MIN_PAGE_SIZE = 4096;  // 最小 Page 大小 4KB
private static final int MAX_CHUNK_SIZE = (int) (((long) Integer.MAX_VALUE + 1) / 2); // 最大 Chunk

三、静态初始化块(static 块)

这是整个类最重要的部分之一,负责计算默认配置。

3.1 Page 大小计算

// 1. 获取 Page 大小(可通过系统属性配置)
int defaultPageSize = SystemPropertyUtil.getInt("io.netty.allocator.pageSize", 8192);

// 2. 验证 Page 大小
try {
    validateAndCalculatePageShifts(defaultPageSize);
} catch (Throwable t) {
    pageSizeFallbackCause = t;
    defaultPageSize = 8192;  // 验证失败,使用默认值
}
DEFAULT_PAGE_SIZE = defaultPageSize;

验证逻辑:

private static int validateAndCalculatePageShifts(int pageSize) {
    // 1. 必须 >= 4096
    if (pageSize < MIN_PAGE_SIZE) {
        throw new IllegalArgumentException("pageSize: " + pageSize + " (expected: " + MIN_PAGE_SIZE + ")");
    }
    
    // 2. 必须是 2 的幂次方
    if ((pageSize & pageSize - 1) != 0) {
        throw new IllegalArgumentException("pageSize: " + pageSize + " (expected: power of 2)");
    }
    
    // 3. 计算 pageShifts(用于位运算优化)
    // 例如:8192 = 2^13,返回 13
    return Integer.SIZE - 1 - Integer.numberOfLeadingZeros(pageSize);
}

3.2 MaxOrder 计算

// 1. 获取 MaxOrder(可通过系统属性配置)
int defaultMaxOrder = SystemPropertyUtil.getInt("io.netty.allocator.maxOrder", 11);

// 2. 验证 MaxOrder
try {
    validateAndCalculateChunkSize(DEFAULT_PAGE_SIZE, defaultMaxOrder);
} catch (Throwable t) {
    maxOrderFallbackCause = t;
    defaultMaxOrder = 11;  // 验证失败,使用默认值
}
DEFAULT_MAX_ORDER = defaultMaxOrder;

验证逻辑:

private static int validateAndCalculateChunkSize(int pageSize, int maxOrder) {
    // 1. maxOrder 必须 <= 14
    if (maxOrder > 14) {
        throw new IllegalArgumentException("maxOrder: " + maxOrder + " (expected: 0-14)");
    }
    
    // 2. 计算 ChunkSize,确保不溢出
    int chunkSize = pageSize;
    for (int i = maxOrder; i > 0; i--) {
        if (chunkSize > MAX_CHUNK_SIZE / 2) {
            throw new IllegalArgumentException(String.format(
                "pageSize (%d) << maxOrder (%d) must not exceed %d", 
                pageSize, maxOrder, MAX_CHUNK_SIZE));
        }
        chunkSize <<= 1;  // chunkSize *= 2
    }
    return chunkSize;
}

计算示例:

pageSize = 8192 (8KB)
maxOrder = 11

chunkSize = 8192 << 11
         = 8192 * 2^11
         = 8192 * 2048
         = 16,777,216 字节
         = 16 MB

3.3 Arena 数量计算(重点)

final Runtime runtime = Runtime.getRuntime();

// 1. 默认最小 Arena 数量 = CPU 核心数 * 2
final int defaultMinNumArena = NettyRuntime.availableProcessors() * 2;

// 2. 计算 ChunkSize
final int defaultChunkSize = DEFAULT_PAGE_SIZE << DEFAULT_MAX_ORDER;  // 16MB

// 3. 计算堆内存 Arena 数量
DEFAULT_NUM_HEAP_ARENA = Math.max(0,
    SystemPropertyUtil.getInt(
        "io.netty.allocator.numHeapArenas",
        (int) Math.min(
            defaultMinNumArena,
            runtime.maxMemory() / defaultChunkSize / 2 / 3)));

// 4. 计算直接内存 Arena 数量
DEFAULT_NUM_DIRECT_ARENA = Math.max(0,
    SystemPropertyUtil.getInt(
        "io.netty.allocator.numDirectArenas",
        (int) Math.min(
            defaultMinNumArena,
            PlatformDependent.maxDirectMemory() / defaultChunkSize / 2 / 3)));

计算逻辑详解:

假设:
- CPU 核心数 = 8
- 堆内存 = 4GB = 4096MB
- ChunkSize = 16MB

计算过程:
defaultMinNumArena = 8 * 2 = 16

方案1:基于 CPU 核心数
numArena = 16

方案2:基于可用内存
numArena = 4096MB / 16MB / 2 / 3
        = 256 / 2 / 3
        = 42.67
        = 42

最终:
DEFAULT_NUM_HEAP_ARENA = min(16, 42) = 16

为什么除以 2 / 3?
- 除以 2:假设每个 Arena 平均有 2 个 Chunk
- 除以 3:内存池不应该占用超过 50% 的可用内存
- 保守估计,避免内存不足

3.4 ThreadCache 配置

// Tiny 缓存大小(< 512B)
DEFAULT_TINY_CACHE_SIZE = SystemPropertyUtil.getInt(
    "io.netty.allocator.tinyCacheSize", 512);

// Small 缓存大小(512B ~ 8KB)
DEFAULT_SMALL_CACHE_SIZE = SystemPropertyUtil.getInt(
    "io.netty.allocator.smallCacheSize", 256);

// Normal 缓存大小(8KB ~ 16MB)
DEFAULT_NORMAL_CACHE_SIZE = SystemPropertyUtil.getInt(
    "io.netty.allocator.normalCacheSize", 64);

// 最大缓存容量(32KB)
DEFAULT_MAX_CACHED_BUFFER_CAPACITY = SystemPropertyUtil.getInt(
    "io.netty.allocator.maxCachedBufferCapacity", 32 * 1024);

// 缓存清理间隔(每分配 8192 次触发一次清理)
DEFAULT_CACHE_TRIM_INTERVAL = SystemPropertyUtil.getInt(
    "io.netty.allocator.cacheTrimInterval", 8192);

// 是否所有线程使用缓存
DEFAULT_USE_CACHE_FOR_ALL_THREADS = SystemPropertyUtil.getBoolean(
    "io.netty.allocator.useCacheForAllThreads", true);

为什么 Tiny 缓存最大?

Tiny (512 个) > Small (256 个) > Normal (64 个)

原因:
1. Tiny 对象(< 512B)最常用
   - 协议头、小消息、控制信息
   - 分配频率最高
   
2. Small 对象(512B ~ 8KB)次之
   - 大部分网络数据包
   - 分配频率中等
   
3. Normal 对象(8KB ~ 16MB)最少
   - 大文件、批量数据
   - 分配频率最低

四、实例变量

// 默认实例(单例)
public static final PooledByteBufAllocator DEFAULT =
    new PooledByteBufAllocator(PlatformDependent.directBufferPreferred());

// Arena 数组
private final PoolArena<byte[]>[] heapArenas;        // 堆内存 Arena
private final PoolArena<ByteBuffer>[] directArenas;  // 直接内存 Arena

// ThreadCache 配置
private final int tinyCacheSize;
private final int smallCacheSize;
private final int normalCacheSize;

// 监控指标
private final List<PoolArenaMetric> heapArenaMetrics;
private final List<PoolArenaMetric> directArenaMetrics;

// 线程本地缓存管理器
private final PoolThreadLocalCache threadCache;

// Chunk 大小
private final int chunkSize;

// 分配器指标
private final PooledByteBufAllocatorMetric metric;

五、构造函数

5.1 构造函数链

// 1. 无参构造
public PooledByteBufAllocator() {
    this(false);  // 不优先使用直接内存
}

// 2. 指定 preferDirect
public PooledByteBufAllocator(boolean preferDirect) {
    this(preferDirect, DEFAULT_NUM_HEAP_ARENA, DEFAULT_NUM_DIRECT_ARENA, 
         DEFAULT_PAGE_SIZE, DEFAULT_MAX_ORDER);
}

// 3. 自定义 Arena 数量
public PooledByteBufAllocator(int nHeapArena, int nDirectArena, 
                              int pageSize, int maxOrder) {
    this(false, nHeapArena, nDirectArena, pageSize, maxOrder);
}

// 4. 完整构造(最终调用)
public PooledByteBufAllocator(boolean preferDirect, int nHeapArena, 
                              int nDirectArena, int pageSize, int maxOrder,
                              int tinyCacheSize, int smallCacheSize, 
                              int normalCacheSize,
                              boolean useCacheForAllThreads, 
                              int directMemoryCacheAlignment) {
    // 实际的初始化逻辑
}

5.2 核心构造逻辑

public PooledByteBufAllocator(boolean preferDirect, int nHeapArena, 
                              int nDirectArena, int pageSize, int maxOrder,
                              int tinyCacheSize, int smallCacheSize, 
                              int normalCacheSize,
                              boolean useCacheForAllThreads, 
                              int directMemoryCacheAlignment) {
    // 1. 调用父类构造
    super(preferDirect);
    
    // 2. 创建 ThreadCache 管理器
    threadCache = new PoolThreadLocalCache(useCacheForAllThreads);
    
    // 3. 保存缓存配置
    this.tinyCacheSize = tinyCacheSize;
    this.smallCacheSize = smallCacheSize;
    this.normalCacheSize = normalCacheSize;
    
    // 4. 计算并验证 ChunkSize
    chunkSize = validateAndCalculateChunkSize(pageSize, maxOrder);
    
    // 5. 验证参数
    checkPositiveOrZero(nHeapArena, "nHeapArena");
    checkPositiveOrZero(nDirectArena, "nDirectArena");
    checkPositiveOrZero(directMemoryCacheAlignment, "directMemoryCacheAlignment");
    
    // 6. 计算 pageShifts
    int pageShifts = validateAndCalculatePageShifts(pageSize);
    
    // 7. 创建堆内存 Arena 数组
    if (nHeapArena > 0) {
        heapArenas = newArenaArray(nHeapArena);
        List<PoolArenaMetric> metrics = new ArrayList<>(heapArenas.length);
        
        for (int i = 0; i < heapArenas.length; i++) {
            PoolArena.HeapArena arena = new PoolArena.HeapArena(
                this, pageSize, maxOrder, pageShifts, chunkSize,
                directMemoryCacheAlignment);
            heapArenas[i] = arena;
            metrics.add(arena);
        }
        heapArenaMetrics = Collections.unmodifiableList(metrics);
    } else {
        heapArenas = null;
        heapArenaMetrics = Collections.emptyList();
    }
    
    // 8. 创建直接内存 Arena 数组
    if (nDirectArena > 0) {
        directArenas = newArenaArray(nDirectArena);
        List<PoolArenaMetric> metrics = new ArrayList<>(directArenas.length);
        
        for (int i = 0; i < directArenas.length; i++) {
            PoolArena.DirectArena arena = new PoolArena.DirectArena(
                this, pageSize, maxOrder, pageShifts, chunkSize,
                directMemoryCacheAlignment);
            directArenas[i] = arena;
            metrics.add(arena);
        }
        directArenaMetrics = Collections.unmodifiableList(metrics);
    } else {
        directArenas = null;
        directArenaMetrics = Collections.emptyList();
    }
    
    // 9. 创建监控指标
    metric = new PooledByteBufAllocatorMetric(this);
}

初始化流程图:

构造函数
    ↓
1. 创建 PoolThreadLocalCache
    ↓
2. 创建 HeapArena 数组
   ├─ HeapArena[0]
   ├─ HeapArena[1]
   └─ ...
    ↓
3. 创建 DirectArena 数组
   ├─ DirectArena[0]
   ├─ DirectArena[1]
   └─ ...
    ↓
4. 创建监控指标

六、核心方法

6.1 分配堆内存

@Override
protected ByteBuf newHeapBuffer(int initialCapacity, int maxCapacity) {
    // 1. 获取当前线程的 ThreadCache
    PoolThreadCache cache = threadCache.get();
    PoolArena<byte[]> heapArena = cache.heapArena;
    
    final ByteBuf buf;
    if (heapArena != null) {
        // 2. 从 Arena 分配(会先尝试 ThreadCache)
        buf = heapArena.allocate(cache, initialCapacity, maxCapacity);
    } else {
        // 3. 没有 Arena,使用非池化分配
        buf = PlatformDependent.hasUnsafe() ?
            new UnpooledUnsafeHeapByteBuf(this, initialCapacity, maxCapacity) :
            new UnpooledHeapByteBuf(this, initialCapacity, maxCapacity);
    }
    
    // 4. 包装成泄漏检测的 ByteBuf
    return toLeakAwareBuffer(buf);
}

6.2 分配直接内存

@Override
protected ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity) {
    // 1. 获取当前线程的 ThreadCache
    PoolThreadCache cache = threadCache.get();
    PoolArena<ByteBuffer> directArena = cache.directArena;
    
    final ByteBuf buf;
    if (directArena != null) {
        // 2. 从 Arena 分配(会先尝试 ThreadCache)
        buf = directArena.allocate(cache, initialCapacity, maxCapacity);
    } else {
        // 3. 没有 Arena,使用非池化分配
        buf = PlatformDependent.hasUnsafe() ?
            UnsafeByteBufUtil.newUnsafeDirectByteBuf(this, initialCapacity, maxCapacity) :
            new UnpooledDirectByteBuf(this, initialCapacity, maxCapacity);
    }
    
    // 4. 包装成泄漏检测的 ByteBuf
    return toLeakAwareBuffer(buf);
}

分配流程:

用户调用:allocator.buffer(1024)
    ↓
newHeapBuffer() 或 newDirectBuffer()
    ↓
1. threadCache.get() → 获取 PoolThreadCache
   ├─ 第一次访问:调用 initialValue() 创建
   └─ 后续访问:直接返回
    ↓
2. cache.heapArena 或 cache.directArena
    ↓
3. arena.allocate(cache, initialCapacity, maxCapacity)
   ├─ 先尝试从 ThreadCache 分配(快)
   └─ 未命中再从 Arena 分配(慢)
    ↓
4. toLeakAwareBuffer(buf) → 包装泄漏检测

七、PoolThreadLocalCache 内部类(重点)

final class PoolThreadLocalCache extends FastThreadLocal<PoolThreadCache> {
    private final boolean useCacheForAllThreads;
    
    PoolThreadLocalCache(boolean useCacheForAllThreads) {
        this.useCacheForAllThreads = useCacheForAllThreads;
    }
    
    @Override
    protected synchronized PoolThreadCache initialValue() {
        // 1. 选择负载最小的 Arena
        final PoolArena<byte[]> heapArena = leastUsedArena(heapArenas);
        final PoolArena<ByteBuffer> directArena = leastUsedArena(directArenas);
        
        final Thread current = Thread.currentThread();
        
        // 2. 判断是否使用缓存
        if (useCacheForAllThreads || current instanceof FastThreadLocalThread) {
            // 创建带缓存的 PoolThreadCache
            final PoolThreadCache cache = new PoolThreadCache(
                heapArena, directArena, 
                tinyCacheSize, smallCacheSize, normalCacheSize,
                DEFAULT_MAX_CACHED_BUFFER_CAPACITY, 
                DEFAULT_CACHE_TRIM_INTERVAL);
            
            // 3. 定时清理缓存
            if (DEFAULT_CACHE_TRIM_INTERVAL_MILLIS > 0) {
                final EventExecutor executor = ThreadExecutorMap.currentExecutor();
                if (executor != null) {
                    executor.scheduleAtFixedRate(
                        trimTask, 
                        DEFAULT_CACHE_TRIM_INTERVAL_MILLIS,
                        DEFAULT_CACHE_TRIM_INTERVAL_MILLIS, 
                        TimeUnit.MILLISECONDS);
                }
            }
            return cache;
        }
        
        // 4. 不使用缓存(缓存大小为 0)
        return new PoolThreadCache(heapArena, directArena, 0, 0, 0, 0, 0);
    }
    
    @Override
    protected void onRemoval(PoolThreadCache threadCache) {
        // 线程结束时释放缓存
        threadCache.free(false);
    }
    
    // 选择负载最小的 Arena
    private <T> PoolArena<T> leastUsedArena(PoolArena<T>[] arenas) {
        if (arenas == null || arenas.length == 0) {
            return null;
        }
        
        PoolArena<T> minArena = arenas[0];
        for (int i = 1; i < arenas.length; i++) {
            PoolArena<T> arena = arenas[i];
            if (arena.numThreadCaches.get() < minArena.numThreadCaches.get()) {
                minArena = arena;
            }
        }
        
        return minArena;
    }
}

负载均衡逻辑:

假设有 4 个 Arena:
Arena[0]: 绑定了 5 个线程
Arena[1]: 绑定了 3 个线程  ← 最少
Arena[2]: 绑定了 4 个线程
Arena[3]: 绑定了 6 个线程

新线程创建 ThreadCache 时:
选择 Arena[1](负载最小)

八、监控和统计方法

// 获取监控指标
@Override
public PooledByteBufAllocatorMetric metric() {
    return metric;
}

// 清理当前线程的缓存
public boolean trimCurrentThreadCache() {
    PoolThreadCache cache = threadCache.getIfExists();
    if (cache != null) {
        cache.trim();
        return true;
    }
    return false;
}

// 打印统计信息
public String dumpStats() {
    int heapArenasLen = heapArenas == null ? 0 : heapArenas.length;
    StringBuilder buf = new StringBuilder(512)
        .append(heapArenasLen)
        .append(" heap arena(s):")
        .append(StringUtil.NEWLINE);
    
    if (heapArenasLen > 0) {
        for (PoolArena<byte[]> a: heapArenas) {
            buf.append(a);
        }
    }
    
    int directArenasLen = directArenas == null ? 0 : directArenas.length;
    buf.append(directArenasLen)
       .append(" direct arena(s):")
       .append(StringUtil.NEWLINE);
    
    if (directArenasLen > 0) {
        for (PoolArena<ByteBuffer> a: directArenas) {
            buf.append(a);
        }
    }
    
    return buf.toString();
}

九、核心要点总结

9.1 职责

  1. 管理 Arena:创建和管理多个 Arena,减少线程竞争
  2. 管理 ThreadCache:为每个线程创建本地缓存,提升性能
  3. 提供分配接口:统一的内存分配入口
  4. 监控统计:提供内存使用情况的监控指标

9.2 关键设计

  1. 多 Arena 设计:

    • 默认 CPU 核心数 * 2
    • 减少线程竞争
    • 负载均衡
  2. ThreadCache 设计:

    • 线程本地缓存
    • 无锁分配
    • 定时清理
卡尔曼滤波器中的Q,R 对于系统状态的估计(滤波结果)所使用的信息来源于两个方面,一个是对系统状态演变模型的了解,包括系统转移矩阵和输入控制矩阵,输入孔质量等,另一方面来自于对系统状态的观测量。从上面公式来看,真正所要滤波得到的结果来自于公式(4)中的系统状态估计值x的某些分量,公式(4)的结果是由公式(1)所得到的状态预测值和来自观测量y计算得到的。所以,在不同算法中,R, Q的取值根据反应的不同量纲,可以有很大的变化,但它们的比值会决定了滤波值应该更多来自于系统模型演化的信息,还是来自于观察信号信息。 阅读详情

相关推荐

永磁同步电机矢量控制(十一)——基于损耗模型的PMSM效率优化策略

本文深入探讨了永磁同步电机(PMSM)基于损耗模型的效率优化策略,详细分析了铜损和铁损的构成与建模方法,并提出了最小损耗控制策略的实现方案。通过与传统MTPA控制的对比,展示了在不同工况下的效率提升效果,同时讨论了工程实现中的关键问题与解决方案,为PMSM的高效运行提供了理论支持和实践指导。

7z8x2c4v6b9的博客 232

Netty源码解析(六)之PooledByteBufAllocator

PooledByteBufAllocator是Netty中比较复杂的一种ByteBufAllocator,因为他涉及到对内存的缓存、分配和释放策略。

benjam1n77的博客 2831

RADIOML 2018.01A数据集在自动调制识别中的实战应用指南

本文提供了RADIOML 2018.01A数据集在自动调制识别(AMR)任务中的完整实战指南。内容涵盖从数据集介绍、数据获取与解包、高效预处理流程,到构建PyTorch数据管道、模型设计(如1D CNN、ResNet)以及训练调参策略。重点阐述了如何利用该数据集训练鲁棒的AI模型,以应对复杂信道环境和低信噪比挑战,并给出了详细的性能评估方法。

plant的博客 174

Netty源码解析之内存管理-PooledByteBufAllocator-PoolArena

Netty源码分析之内存管理

黄裳博客 2374

【AI生成】市面上主流自组网厂家的技术及市场研究

经过对全球自组网产业技术特征与市场格局的系统分析,本文得出以下核心结论:技术演进呈现智能化与融合化双轨路径 当前自组网技术创新已突破传统组网架构局限,形成"协议优化-架构创新-场景适配"的递进式发展路径。国际厂商聚焦智能算法应用,如Silvus采用深度学习实现动态拓扑优化,传输时延较传统方案降低37%;国内企业则侧重异构网络融合,中国移动设计院提出的5G LAN架构使工业场景通信可靠性提升至99.99%。

qq_31310977的博客 1698

Nacos 2.3.2与PostgreSQL的Docker化部署实战

本文详细介绍了Nacos 2.3.2与PostgreSQL的Docker化部署实战,包括环境准备、数据库配置、镜像获取与导入、容器部署及常见问题排查。通过Docker容器化技术,结合PostgreSQL的稳定性和扩展性,为微服务架构提供高效的服务发现和配置管理解决方案。

k5l6m的博客 284

Netty内存管理--内存分配器PooledByteBufAllocator

本篇聊聊直接使用的内存分配器PooledByteBufAllocator基于实际场景做了一些额外的优化。

技术进步那些的事 1280

JFET放大电路实例设计仿真

参照《晶体管电路设计》中的例子 JFET 2SK184 JFET 2SK184 数据手册如下 电路设计 共源放大 步骤:1、静态工作点 2N4416 1ma 2、RD和RS A=5 5:1 RS 2V /1m=2k RD 5k 3、偏压VG 根据传输特性 VGS-ID vgs=-0.7 vg=2-0.7=1.3 400k^2/50k...

f的博客 7443

Netty学习——源码篇12 Netty池化内存管理机制

首先调用leastUsedArena()方法分别获得类型为PoolArena的heapArena和directArena对象。那么heapArena和directArena对象是在哪里初始化呢?其实就是创建了一个固定大小的PoolArena数组,数组大小由传入的参数nHeapArena和nDirectArena决定。发现nHeapArena和nDirectArena是通过DEFAULT_NUM_HEAP_ARENA, DEFAULT_NUM_DIRECT_ARENA 这两个常量默认赋值的。

geminigoth的博客 2381

vCenter Server出现no healthy upstream的解决方法

可以通过"VMware vCenter Server Management(服务)"来排查问题,在网页里面找到“服务”模块,会发现有很多服务没有启动起来,而且手动启动也无法启动。7.0 地址后,页面出现“no healthy upstream”,无法正常登录vCenter,重启后依旧如此,该故障的前提是没有对vCenter做过任何配置,如下图所示。于是用命令查询是否有证书过期,发现真有多个服务依赖的证书在当天早上过期。使用如下命令尝试打开服务发现不分服务可以打开,不分服务无法打开。

1万+

改进YOLOv9的CT图像肺结节检测与分类算法:从原理到实战

本文将详细介绍如何改进YOLOv9算法,使其更好地适应CT图像肺结节检测与分类任务。我们将从数据集准备、模型改进、训练优化到最终部署,完整呈现一个端到端的深度学习项目,并提供完整的代码实现。

YOLO 188

Netty内存泄漏终极解决方案:PooledByteBufAllocator线程缓存计数深度解析

Netty作为高性能网络应用框架,其内存管理机制一直是开发者的关注焦点。本文将深入剖析Netty中PooledByteBufAllocator的线程缓存计数问题,帮助开发者彻底解决内存泄漏难题。😊 ## 什么是PooledByteBufAllocator? PooledByteBufAllocator是Netty框架中的核心内存分配器,它通过池化技术大幅提升内存分配效率。然而,正是这种高效的

gitblog_00721的博客 518

句向量(句嵌入)模型sent2vec的训练及应用

本文讨论NLP中的句向量模型(sent2vec),也就是将一个完整的句子映射成一个实数向量的技术。这方面已经发表的成果也是比较多的,本文中所涉及的技术主要源自NAACL 2018的一篇论文,其中提出的sent2vec模型可以理解为词嵌入技术中经典的CBOW方法的扩展,该所谓的扩展中一个重要改进就是引入了n-gram

白马负金羁 1万+

Netty学习之旅:源码分析Netty内存池分配基础数据结构(PoolArena、PoolChunk、PoolSubpage)

1、Netty 内存分配基础数据结构 Netty 预先申请一大块连续的内存(用 PoolArena 类表示),然后每一 PoolArena 包含一系列的 Chunk, 用 PoolChunk 表示,然后每一个 Chunk 包含一列的 PoolSubpage,每个 PoolSubpage 由大小相等的块(Region)组成,每个 PoolSubpage 块大小由第一次从 PoolSubpage申请...

中间件兴趣圈 5311

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Netty 4.2.x 源码深度解析 (二):FastThreadLocal —— Netty 自研线程局部变量

本文针对 JDK ThreadLocal 哈希冲突、内存泄漏、计算开销大等痛点,解析 Netty 4.2.x 自研的 FastThreadLocal 实现。其通过全局递增索引 + 数组存储实现无冲突 O (1) 存取,依托 InternalThreadLocalMap 完成数据读写与扩容。借助 FastThreadLocalThread 实现快速访问路径,搭配 FastThreadLocalRunnable 自动清理变量,规避线程池内存泄漏,同时适配虚拟线程,兼顾高性能与内存安全。

于云原生深处,追寻架构与代码的优雅 517

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

从0到1理解Netty内存管理:ByteBuf池化技术如何拯救OOM危机

Netty作为高性能网络编程框架,其内存管理机制是实现高并发场景下稳定运行的核心保障。本文将深入剖析Netty的ByteBuf池化技术,带你理解它如何通过创新的内存复用机制解决传统NIO编程中的内存泄漏问题,让你的应用轻松应对高负载挑战。 ## 为什么Netty需要特殊的内存管理? 在传统Java NIO编程中,ByteBuffer的创建和销毁成本高昂,尤其是堆外内存的分配回收会导致频繁的系统

gitblog_00903的博客 877

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

2.4 java面试题:Netty

Netty 是一个,用于快速开发高性能、高可靠性的网络 IO 程序。它在 Java 领域中的地位,就像“网络编程的 Spring”,几乎统治了所有需要自定义协议的中间件和分布式组件。老练的 Java 工程师说 Netty,不仅要讲“是什么”,还要讲清它,以及。

你是人间四月天 220

Java大厂面试全攻略:核心知识点与实战技巧

Java技术面试是开发者职业发展的重要关卡,尤其在大厂面试中,考察点往往涵盖从语言基础到分布式系统的全栈能力。理解JVM内存模型、并发编程原理等底层机制是构建技术深度的基础,而分布式事务、缓存设计等实战场景则考验工程实践能力。在系统设计中,高并发场景下的架构决策如秒杀系统、Feed流设计等高频考点,需要结合Redis、Kafka等技术组件进行方案优化。面试准备应注重源码级理解,比如ConcurrentHashMap的演进或Spring循环依赖解决机制,同时通过真实性能优化案例展示问题解决能力。掌握这些核心知

weixin_33937913的博客 437

Netty内存池化技术 PooledByteBufAllocator 深度解析

Netty的PooledByteBufAllocator采用分层内存池设计,通过PoolThreadLocalCache为每个线程提供本地缓存,减少锁竞争。核心组件包括管理堆/直接内存的PoolArena、4MB大小的PoolChunk,以及处理小内存的PoolSubpage。分配流程优先从线程缓存获取,未命中则访问PoolArena,并支持非池化回退。系统通过validateAndCalculate方法验证关键参数,确保内存结构安全。该设计实现了高效内存分配与回收,内置泄漏检测,通过多Arena负载均衡

lifallen的博客 1512

Netty PooledByteBufAllocator

Netty PooledByteBufAllocator 池化内存分配 newDirectBuffer() 和 newHeapBuffer() 两个主要方法. @Override protected ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity) { PoolThreadCache cache = threadCache.get(); // 获取 线程局部缓存 PoolThreadCache PoolArena&lt

flyingzc的博客 684

13、Netty内存池之PooledByteBufAllocator

一、PooledByteBufAllocator的创建 PooledByteBufAllocator顾名思义,就是一个用于分配PooledByteBuf的分配器 现在有以下例子程序 public class Test { public static void main(String[] args) { PooledByteBufAllocator allocator =...

zhen_hong的博客 2006

Netty中的那些坑

最近开发了一个纯异步的redis客户端,算是比较深入的使用了一把netty。在使用过程中一边优化,一边解决各种坑。而这些坑大部分基本上是Netty 4对Netty 3的改进部分引起的。 注:这里说的坑不是说netty不好,只是如果这些地方不注意,或者不去看netty的代码,就有可能掉进去了。 坑1: Netty 4的线程模型转变 在Netty 3的时候,upstream是在IO线

xtqve的专栏 3086

Netty源码之PooledByteBufAllocator

在这个类中我们主要从下面这个方法开始看: protected ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity) { //从当前线程中拿到一个cache对象 PoolThreadCache cache = threadCache.get(); //从cache中获得内存管理的顶层“竞技场” ...

m0_37343985的博客 1114

netty源码解析(4.0)-28 ByteBuf内存池:PooledByteBufAllocator-把一切组装起来

  PooledByteBufAllocator负责初始化PoolArena(PA)和PoolThreadCache(PTC)。它提供了一系列的接口,用来创建使用堆内存或直接内存的PooledByteBuf对象,这些接口只是一张皮,内部完全使用了PA和PTC的能力。初始化过程分两个步骤,首先初始化一系列的默认参数,然后初始化PTC对象和PA数组。 默认参数和它们的值   DEFAULT_...

自带buff 595

netty源码阅读之ByteBuf之内存分配器ByteBufAllocator

我们分三部分讲解ByteBufAllocator: 1、ByteBufAllocator功能 2、AbstractByteBufAllocator 3、ByteBufAllocator两大子类   一、ByteBufAllocator功能 查看ByteBufAllocator源码: /** * Implementations are responsible to allocat...

翻身咸鱼的博客 3775

netty4.0源码分析之PooledByteBufAllocator

概述 netty 内存管理的高性能主要依赖于两个关键点: 内存的池化管理 使用堆外直接内存(Direct Memory) 从netty 4开始,netty加入了内存池管理,采用内存池管理比普通的new ByteBuf性能提高了数十倍。 首先介绍PoolChunk, 该类主要负责内存块的分配与回收,首先来看看两个重要的术语: page: 可以分配的最小的...

lzf的博客 852
上一篇: Netty源码分析---Epoll空轮询Bug深度解析
下一篇: Netty源码分析---Recycler详解
不早睡不改名@
博客等级 码龄5年 536粉丝 306原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值