netty源码之ByteBuf详解

netty byteBuf readBytes方法的小坑(内存溢出,LEAK问题) netty LEAK readBytes 阅读详情

目录

          一、背景简介

          二、ByteBuf和ByteBuffer对比

          三、源码


      一、背景简介

ByteBuf,顾名思义,就是字节缓冲区,是Netty中非常重要的一个组件。熟悉jdk NIO的同学应该知道ByteBuffer,正是因为jdk原生ByteBuffer使用比较复杂,某些场景下性能不是太好,netty开发团队重新设计了ByteBuf用以替代原生ByteBuffer。

     二、ByteBuf和ByteBuffer对比

ByteBuf比JDK中原生的ByteBuffer设计更加优秀,某些场景下时间复杂度更小,ByteBuf有读和写两个指针readindex和writeIndex,而ByteBuffer只有一个指针,需要通过flip()方法在读和写之间进行模式切换,单一场景下只能做一件事情,不同场景需要来回切换。而ByteBuf将读和写进行了分离,使用者可以将更多地精力集中在业务逻辑处理上,而不必太过于关心现在是读模式还是写模式。

下面用图示来展示ByteBuf和ByteBuffer工作原理:

①、ByteBuffer

ByteBuffer依靠flip()来切换模式,在读模式下调用flip()切换为写模式,在写模式下limit和capacity相等,position标识当前写的位置。在写模式下调用flip()切换为读模式,在读模式下position回到起始位置开始读,limit回到position位置表示能读到多少数据,capacity不变表示缓存区容量大小。

capacity:在读/写模式下都是固定的,就是缓冲区容量大小。

position:读/写位置指针,表示当前读(写)到什么位置。

limit:在写模式下表示最多能写入多少数据,此时和capacity相同。在读模式下表示最多能读多少数据,此时它的值等于缓存区中实际数据量的大小。

②、ByteBuf

ByteBuf主要是通过readerIndex 和 writerIndex两个指针进行数据的读和写,整个ByteBuf被这两个指针最多分成三个部分,分别是可丢弃部分,可读部分和可写部分

刚初始化的时候,整个缓冲区还没有数据,读写指针都指向0,所有的内容都是可写部分,此时还没有可读部分和可丢弃部分,如下:

当写完N个字节数据后,读指针仍然是0,因为还没有开始进行读事件,写指针向后移动了N个字节的位置,如下:

当开始读数据并且读取M个字节数据之后(M<N)写指针位置不变,读指针后移动了M个字节的位置,如下:

当可丢弃部分数据被清空之后,readerindex重新回到起始位置,writerindex的位置为writerindex的值减去之前的readerindex,也就是M,相关图示如下:

调用clear之后,writerindex和readerinde全部复位为0。它不会清除缓冲区内容(例如,用填充0),而只是清除两个指针。更改的读写指针的值,每个位置上原本的字节内容并没有发生改变,只是变成了可写状态而已。另请注意,此操作的语义不同于Buffer.clear()。

         三、源码

明白了ByteBuf工作原理之后,ByteBuf相关的api就很好理解了,在此附上netty官方api文档,以供参阅:

https://netty.io/4.1/api/overview-summary.html。

我们在这里看下netty扩容相关源码逻辑。

扩容肯定是在写入数据的时候会由相关逻辑判断,我们随便进入一个写入字节的api方法。

public abstract ByteBuf writeBytes(byte[] src);

进入到其抽象子类AbstractByteBuf中。

    @Override
    public ByteBuf writeBytes(byte[] src) {
        writeBytes(src, 0, src.length);
        return this;
    }
    @Override
    public ByteBuf writeBytes(byte[] src, int srcIndex, int length) {
        ensureAccessible();
        ensureWritable(length);
        setBytes(writerIndex, src, srcIndex, length);
        writerIndex += length;
        return this;
    }

首先ensureAccessible进行安全校验,每种尝试访问缓冲区内容的方法都应调用此方法,以检查缓冲区是否已释放。然后ensureWritable判断是否可写,扩容相关逻辑就在这里进行判断,如果缓冲区可写执行setBytes进行数据写入,然后writerindex向后移动length的位置,最后将ByteBuf对象进行返回。我们重点看ensureWritable。

    @Override
    public ByteBuf ensureWritable(int minWritableBytes) {
        if (minWritableBytes < 0) {
            throw new IllegalArgumentException(String.format(
                    "minWritableBytes: %d (expected: >= 0)", minWritableBytes));
        }
        ensureWritable0(minWritableBytes);
        return this;
    }

直接进入ensureWritable0(minWritableBytes)方法中,此时minWritableBytes就是我们计划需要申请的内存大小空间。

        private void ensureWritable0(int minWritableBytes) {
         // 安全检查,保证写入之前是可访问的
         //ensureAccessible();
​
         // 可写,不必扩容
        if (minWritableBytes <= writableBytes()) {
            return;
        }
​
        //下标越界
        if (minWritableBytes > maxCapacity - writerIndex) {
            throw new IndexOutOfBoundsException(String.format(
                    "writerIndex(%d) + minWritableBytes(%d) exceeds maxCapacity(%d): %s",
                    writerIndex, minWritableBytes, maxCapacity, this));
        }
​
        //达到临界条件,开始执行扩容逻辑
        // 计算新的容量,实际上为当前容量扩容至2的幂次方大小(具体是多少需要进行后续判断和计算)
        int newCapacity = alloc().calculateNewCapacity(writerIndex + minWritableBytes, maxCapacity);
        // 扩容后的容量
        capacity(newCapacity);
    }

可以看到真正开辟内存空间新容量逻辑处理的是 alloc().calculateNewCapacity(writerIndex + minWritableBytes, maxCapacity)执行的,进入到方法里面。

来到其实现类AbstractByteBufAllocator的calculateNewCapacity方法。

     @Override  
    public int calculateNewCapacity(int minNewCapacity, int maxCapacity) {
        if (minNewCapacity < 0) {
            throw new IllegalArgumentException("minNewCapacity: " + minNewCapacity + " (expectd: 0+)");
        }
        if (minNewCapacity > maxCapacity) {
            throw new IllegalArgumentException(String.format(
                    "minNewCapacity: %d (expected: not greater than maxCapacity(%d)",
                    minNewCapacity, maxCapacity));
        }
        // 扩容的阈值,4兆字节大小
        final int threshold = 1048576 * 4;
        if (minNewCapacity == threshold) {
            return threshold;
        }
       //如果计划一共需要的内存容量大小大于阈值,则需要和最大容量j进行比较
        if (minNewCapacity > threshold) {
            int newCapacity = minNewCapacity / threshold * threshold;
            if (newCapacity + threshold > maxCapacity) {
                newCapacity = maxCapacity;
            } else {
                newCapacity += threshold;
            }
            return newCapacity;
        }
​
        //如果计划一共需要的内存容量大小小于阈值,则以64为基数进行倍增
        int newCapacity = 64;
        while (newCapacity < minNewCapacity) {
            newCapacity <<= 1;
        }
        return Math.min(newCapacity, maxCapacity);
    }

minNewCapacity是我们计划一共需要的内存容量大小,maxCapacity是最大缓冲区容量大小。首先判断minNewCapacity 是否小于零或者minNewCapacity 是否大于maxCapacity,满足任一都抛出异常信息,然后判断我们计划一共需要的内存容量大小minNewCapacity 是否等于了阈值4M:

①、如果等于了阈值,新容量大小就是阈值4M。

②、如果计划一共需要的内存容量大小大于阈值,则maxCapacity和minNewCapacity 相对于阈值的整数倍再加上一个阈值进行大小判断,如果大于maxCapacity,则新容量最大就是maxCapacity,返回maxCapacity,如果小于maxCapacity,则相当于按照阈值的2倍进行扩容。

③、如果计划一共需要的内存容量大小小于阈值,则以64为基数只要小于我们计划需要的内存容量大小,就2倍扩容,最后选取循环后的扩容值和最大值两个值其中的较小者。

至此扩容就完成了,总结来说就是在扩容过程中有一个扩容需要容量的一个阈值4M,如果我们需要的内存空间等于这个阈值,那么扩容后的容量就是阈值大小,如果我们需要的内存容量大小大于阈值或者小于阈值,其扩容逻辑判断和扩容后返回的容量大小是不同的。但是最终扩容后的容量大小总是2的幂次方大小并且不会比maxCapacity大。

个人才疏学浅、信手涂鸦,netty框架更多模块解读相关源码持续更新中,感兴趣的朋友请移步至个人公众号,谢谢支持😜😜......

公众号:wenyixicodedog

Netty源码分析(五)—ByteBuf源码分析 Netty源码分析(五)—ByteBuf源码分析 在进行数据传输时往往需要使用缓冲区,Java NIO中使用Buffer作为缓冲区;七种基本数据类型都有自己的缓冲区实现,最常使用的是ByteBuffer,但是ByteBuffer也有局限性; Netty实现了缓冲区的池化技术,在一定程度上减少了频繁内存分配和GC带来的性能损耗 个人主页:tuzhenyu’s page 阅读详情

相关推荐

利用gprMax与Matlab实现SFCW雷达信号的高效仿真与优化

本文详细介绍了如何结合gprMax与Matlab实现SFCW雷达信号的高效仿真与优化。通过利用gprMax获取地下场景的冲激响应,并在Matlab中运用卷积与信号处理技术,可大幅提升SFCW雷达系统仿真的效率与灵活性,为探地雷达研究与设计提供强大工具。

book8的博客 707

Netty ByteBuf 按位读操作

前言 最近与一个刚接触Netty的学生关于Netty读字节流方面的操作进行讲解,可能对后来同学有点点帮助,所以整理出来供大家探讨。 ByteBuf读操作 ByteBuf读操作我们常用的有一下几种: ByteBuf.readByte() 读一个字节,有符号 ByteBuf.readUnsignedByte() 读一个字节,无符号 ByteBuf.readShort()读连续的两个字节,有符号 ByteBuf....

谁念西风独自凉 6312

微信支付V2,jsapi支付拉起收银台报错:调用支付JSAPI缺少参数:total_fee

拉起收银台报错

m0_54355172的博客 3873

ByteBuf 操作

public static void main(String[] args) throws UnsupportedEncodingException { // 1.创建一个非池化的ByteBuf,大小为14个字节 ByteBuf buffer = Unpooled.buffer(14); System.out.println("1.创建一个非池化的ByteBuf,大小为14个字节"); System.out.println("ByteBuf空间大小:" + buffer.ca...

weixin_40118044的博客 1836

PCRNet: Point Cloud Registration Network using PointNet Encoding

PCRNet算是在ModelNet40这种object-centric数据集上用deep-learning做配准最好入手的一篇文章了,整体架构涉及简洁明了,一句话描述就是简单粗暴,话不多说,直接上网络架构图: Work Flow: 首先对输入source (N×3N \times 3N×3)与template (M×3M \times 3M×3)进行PointNet操作,即MLP + max-pooling后,分别得到描述各自点云的维度为1024的global feature vector:Φ(PS).

dloading7的博客 1648

1篇1章3节:R 语言的产生与发展轨迹(更新2024/08/14)

药物的研究阶段包括靶标确定、生物学模型建立、新化学实体的发现和优化新化学实体四个关键环节。每个环节都在药物研发过程中发挥着至关重要的作用。通过科学严谨的方法和技术手段,研究人员能够在药物研发过程中不断探索和优化,从而发现和开发出具有高效、安全性的候选药物,为疾病治疗提供更多的选择和希望。

MD Code 2669

Netty:ByteBuf写入数据、读出数据

Netty:ByteBuf写入数据、读出数据

听海边涛声 7825

QLineEdit控件: 实现IP地址输入框(基于编辑信号)

在开发网络应用程序时,经常需要用户输入IP地址。直接使用普通输入框容易导致格式错误,用户体验也较差。本文将手把手教你用Qt的QLineEdit控件实现一个智能IP地址输入框。即使你是刚接触Qt的新手,也能通过本文理解核心实现原理。

u011186532的专栏 652

Netty-bytebuf

Netty提供了ByteBuf来替代Java NIO的ByteBuffer缓冲区,以操纵内存缓冲区。ByteBuf的优势ByteBuf的逻辑部分ByteBuf是一个字节容器,内部是一个字节数组。从逻辑上来分,字节容器内部可以分为四个部分,具体如图6-14所示。 第一个部分是已用字节,表示已经使用完的废弃的无效字节;第二部分是可读字节,这部分数据是ByteBuf保存的有效数据,从ByteBuf中读取的数据都来自这一部分;第三部分是可写字节,写入到ByteBuf的数据都会写到这一部分中;第四部分是可扩容字节,表

yitian881112的专栏 1205

《MPDIoU:边界框回归的高效革新与YOLOv8集成实战指南》

摘要: MPDIoU(多优先级距离IoU)通过引入中心距离、形状差异和尺度变化的三步优化策略,解决了传统IoU在目标检测中的尺度敏感、收敛低效和场景局限问题。相较于GIoU、DIoU等主流方法,MPDIoU在精度、速度和鲁棒性上实现全面提升,尤其在复杂场景和小目标检测中表现突出。通过代码集成和训练优化,MPDIoU在YOLOv8中显著提升COCO数据集AP指标,并在智能安防(密集行人检测)和工业质检(微小缺陷定位)等垂直领域验证了其应用价值。未来研究方向包括动态权重调整和多模态融合,进一步拓展边界框回归的精

m0_64661770的博客 159

uniapp(vue3)- 详解安装/使用pinia报错reportJSException >>>> exception function:createInstanceContext, excepti

uniapp vue3 pinia报错reportJSException >>>> exception function:createInstanceContext, exception:white screen cause create instanceContext failed,check js stack -> at useStore,H5网页,微信小程序,安卓App,苹果App,nvue,uniapp安装使用pinia出现报错at useStore,uniapp+vue3+ts 使用pinia报

🏆 前端领域优质创作者 4049

Netty ByteBuf 详解及详细源码展示

Netty的ByteBuf优化了Java NIO ByteBuffer的读写分离、动态扩容和内存管理问题,通过独立指针(readerIndex/writerIndex)和池化技术(PooledByteBufAllocator)提升性能。其核心实现包括堆/直接内存分配、零拷贝(slice()/CompositeByteBuf)及泄漏检测机制。源码中,AbstractByteBuf处理基础操作,PooledByteBuf实现内存复用,支持自动扩容(默认翻倍策略)。典型应用如网络编解码和零拷贝

csdn_tom_168的博客 895

利用ADS建立MIPI D-PHY链路仿真流程

由于MIPI D-PHY的速率并不算高,因此,PCB设计难度通常不大,主要做好差分线的等长、阻抗的连续性、端口处的阻抗优化以及控制好走线的长度,拿到满意的结果还是较为轻松的,最后,建立流程化的仿真工程文件,可以保存为模板,方便日后的设计复用,非常方便。

一只豌豆象的博客 3571

Netty源码ByteBuf详解

作为一个高性能网络编程框架,Netty的字节容器ByteBuf相较于JDK标准库自带的ByteBufferByteBuf按照分类可以分为堆内内存和直接内存,前者分配在JVM堆内存中,由JVM进行管理和GC,后者直接分配在本地内存上,需要我们进行手动释放,但是性能要好于前者。ByteBuf为读写操作分别提供读写指针,通过读写指针我们可以快速定位、设置指定偏移量上的数据。ByteBuf会根据使用情况进行动态扩容和缩容,使得它更加灵活,可以适应不同的数据大小。ByteBuf。

禅与计算机程序设计的艺术 612

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Netty(九)——ByteBuf源码之析

       ByteBuf在Netty占据着中重要的位置,上篇《Netty——ByteBuf功能之说》讲了ByteBuf的工作原理和重要功能介绍。这篇从源码的角度来看ByteBuf。首先,来看一下主要的类继承结构图:        我们从两个角度看下上图:        从内容分配角度上分为:1,堆内存(HeapByteBuf)字节缓冲区,特点是内存的分配和回收速度快,可被JVM自动回收...

学会改变自己——才能突破 1561

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Netty Review - ByteBuf内存池源码解析

ByteBuf 内存池是 Netty 中用于管理 ByteBuf 对象的一种机制,旨在提高内存的使用效率和性能。

小工匠 7394

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

10、Netty-源码-ByteBuf源码解读

待更新

爱欧米 131

Netty 权威指南笔记(五):ByteBuf 源码解读

Java 本身提供了 ByteBuffer 类,为什么 Netty 还要搞一个 ByteBuf 类呢?因为 ByteBuffer 类有着许多缺点: 1. ByteBuffer 长度固定,无法动态伸缩。 2. ByteBuffer 只有一个位置指针 position,读写的时候需要手工调用 flip 和 rewind 方法进行模式转换,操作繁琐,容易出错。 3. 功能太少,缺少一些高级特性。

albon arith 1815

Netty源码—7.ByteBuf原理三

这些固定大小分别有:tiny类型规则的是16B的整数倍直到498B,small类型规则的有512B、1K、2K、4K,normal类型规定的有8K、16K、32K。PoolSubpage中的chunk属性表示该SubPage从属于哪个PoolChunk,PoolSubpage中的elemSize属性表示该SubPage是以多大的数值进行划分的,PoolSubpage中的bitmap属性会用来记录该SubPage的内存分配情况,一个Page里的PoolSubpage会连成双向链表。

mjunz的博客 1110

Netty Review - ByteBuf扩容机制源码解析

ByteBuf 扩容机制是指在写入数据时,如果当前容量不足以容纳新增的数据,则需要进行动态扩容,以适应数据量的增长。容量检查在写入数据之前,会先检查当前可写入的容量是否足够。这通常是通过比较写索引和容量之间的关系来实现的。如果当前可写入容量不足,就需要进行扩容操作。内存分配当需要扩容时,会分配一个更大的内存空间来存储数据。这个内存空间的大小通常由扩容策略决定,可以是固定大小的增量,也可以是根据某种规则动态计算的。数据迁移在分配更大的内存空间后,原有的数据需要从旧的内存空间复制到新的内存空间中。

小工匠 7142

Netty源码—ByteBuf原理二

首先从线程对应的PoolThreadCache里获取一个PoolArena,然后从PoolArena的一个ChunkList中取出一个Chunk进行内存分配。接着,在这个Chunk上进行内存分配时,会判断需要分配的内存大小是否大于一个Page的大小。如果需要分配的内存超过一个Page的大小,那么就以Page为单位进行内存分配。如果需要分配的内存远小于一个Page的大小,那么就会找一个Page并把该Page切分成多个SubPage然后再从中选择。

sdgfafg_25的博客 1092

Netty源码阅读之ByteBuf简析(二)

前面对于Netty中的ByteBuf缓存做了一下简单的介绍,下面将围绕源码,对于其中的几个特性进行分析。 1.扩容机制 首先来聊下Bytebuf的扩容机制,这个机制也是Netty比较强悍的地方,而我们知道JDK自带的ByteBuffer是无法扩容的,在Bytebuf创建的时候,我们通常会设置一个初始容量,在我们写数据的时候,如果写指针超过了设置的初始容量,那么Bytebuf将进行扩容,废话不多说,下面我们直接通过源码来一探究竟吧: public ByteBuf writeBytes(ByteBuf

记忆碎片 1028

Netty源码分析——ByteBuf

目录 1、ByteBuffer介绍 2、ByteBuffer缺点 3、ByteBuf介绍 4、ByteBuf常用API 5、ByteBuf转换成标准的ByteBuffer 6、ByteBuf源码分析 7、最简单的将接收到的消息打印出来 Netty 里面数据读写是以 ByteBuf 为单位进行交互的,ByteBuf是Byte数组的缓冲区,像java里的ByteBuffer 1、By...

weixin_43599368的博客 663

netty源码阅读之ByteBuf之ByteBuf分类

ByteBuf分类,从下面三个维度: 1、Pooled和Unpooled 2、Unsafe和非Unsafe 3、Heap和Direct     一、Pooled和Unpooled 这两个的区别是使用的内存是从预先分配好的内存还是未分配的内存取,第一个从预先分配好的内存去取一段连续的内存,第二种调用系统api直接去申请一块内存。 在分配bytebuf的时候,会有一个分配器: 分...

翻身咸鱼的博客 1054

Netty源码—7.ByteBuf原理二

PooledByteBufAllocator的heapBuffer()方法通过其newHeapBuffer()方法执行代码heapArena.allocate()时,首先会调用PoolArena的allocate()方法,然后会调用PoolArena的allocateNormal()方法,接着会调用PoolChunk的allocate()方法,并最终调用到PoolChunk的allocateRun()方法进行Page级别的内存分配。每一个Entry都代表了某一个Chunk下的一段连续内存。

weixin_41494314的博客 53
上一篇: netty单线程模型
下一篇: netty粘包拆包之FixedLengthFrameDecoder解码器
wenyixicodedog
博客等级 码龄8年 87粉丝 116原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值