常见面试题-Netty中ByteBuf类

了解 Netty 中的 ByteBuf 类吗?

答:

在 Java NIO 编程中,Java 提供了 ByteBuffer 作为字节缓冲区类型(缓冲区可以理解为一段内存区域),来表示一个连续的字节序列。

Netty 中并没有使用 Java 的 ByteBuffer,而是使用了新的缓冲类型 ByteBuf,特性如下:

  • 允许自定义缓冲类型

  • 复合缓冲类型中内置的透明的零拷贝实现

  • 开箱即用的动态缓冲类型,具有像 StringBuffer 一样的动态缓冲能力

  • 不再需要调用 flip() 方法

    Java 的 ByteBuffer 类中,需要使用 flip() 来进行读写两种模式的切换

  • 正常情况下具有比 ByteBuffer 更快的响应速度

Java 中的 ByteBuffer:

主要需要注意有 3 个属性:position、limit、capacity

  • capacity:当前数组的容量大小
  • position:写入模式的可写入数据的下标,读取模式的可读取数据下标
  • limit:写入模式的可写入数组大小,读取模式的最多可以读取数据的下标

假如说数组容量是 10,那么三个值初始值为:

position = 0
limit = 10
capacity = 10

假如写入 4 个字节的数据,此时三个值如下:

position = 4
limit = 10
capacity = 10

如果切换到读取数据模式(使用 flip()),会改变上边的三个值,会从 position 的位置开始读取数据到 limit 的位置

position = 0
limit = 4
capacity = 10

Netty 中的 ByteBuf:

ByteBuf 主要使用两个指针来完成缓冲区的读写操作,分别是: readIndexwriteIndex

  • 当写入数据时,writeIndex 会增加
  • 当读取数据时,readIndex 会增加,但不会超过 writeIndex

ByteBuf 的使用:

public static void main(String[] args) {
    ByteBuf buffer = Unpooled.buffer(10);
    System.out.println("----------初始化ByteBuf----------");
    printByteBuffer(buffer);

    System.out.println("----------ByteBuf写入数据----------");
    String str = "hello world!";
    buffer.writeBytes(str.getBytes());
    printByteBuffer(buffer);

    System.out.println("----------ByteBuf读取数据----------");
    while (buffer.isReadable()) {
        System.out.print((char)buffer.readByte());
    }
    System.out.println();
    printByteBuffer(buffer);


    System.out.println("----------ByteBuf释放无用空间----------");
    buffer.discardReadBytes();
    printByteBuffer(buffer);

    System.out.println("----------ByteBuf清空----------");
    buffer.clear();
    printByteBuffer(buffer);
}
private static void printByteBuffer(ByteBuf buffer) {
    System.out.println("readerIndex:" + buffer.readerIndex());
    System.out.println("writerIndex:" + buffer.writerIndex());
    System.out.println("capacity:" + buffer.capacity());
}
/**输出**/
----------初始化ByteBuf----------
readerIndex:0
writerIndex:0
capacity:10
----------ByteBuf写入数据----------
readerIndex:0
writerIndex:12
capacity:64
----------ByteBuf读取数据----------
hello world!
readerIndex:12
writerIndex:12
capacity:64
----------ByteBuf释放无用空间----------
readerIndex:0
writerIndex:0
capacity:64
----------ByteBuf清空----------
readerIndex:0
writerIndex:0
capacity:64

ByteBuf 的 3 种使用模式:

ByteBuf 共有 3 种使用模式:

  • 堆缓冲区模式(Heap Buffer)

    堆缓冲区模式又称为 “支撑数据”,其数据存放在 JVM 的堆空间

    优点:

    • 数据在 JVM 堆中存储,可以快速创建和释放,并且提供了数组直接快速访问的方法

    缺点:

    • 每次数据与 IO 进行传输时,都需要将数据复制到直接缓冲区(这里为什么要将数据复制到直接缓冲区的原因在上边的 直接内存比堆内存快在了哪里? 问题中已经讲过)

    创建代码:

    ByteBuf buffer = Unpooled.buffer(10);
    
  • 直接缓冲区模式(Direct Buffer)

    直接缓冲区模式属于堆外分配的直接内存,不占用堆的容量

    优点:

    • 使用 socket 传输数据时性能很好,避免了数据从 JVM 堆内存复制到直接缓冲区

    缺点:

    • 相比于堆缓冲区,直接缓冲区分配内存空间和释放更为昂贵

    创建代码:

    ByteBuf buffer = Unpooled.directBuffer(10);
    
  • 复合缓冲区模式(Composite Buffer)

    本质上类似于提供一个或多个 ByteBuf 的组合视图

    优点:

    • 提供一种方式让使用者自由组合多个 ByteBuf,避免了复制和分配新的缓冲区

    缺点:

    • 不支持访问其支撑数据,如果要访问,需要先将内容复制到堆内存,再进行访问

    创建代码:

    public static void main(String[] args) {
    //        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Test.class);
        // 创建一个堆缓冲区
        ByteBuf heapBuf = Unpooled.buffer(2);
        String str1 = "hi";
        heapBuf.writeBytes(str1.getBytes());
        // 创建一个直接缓冲区
        ByteBuf directBuf = Unpooled.directBuffer(5);
        String str2 = "nihao";
        directBuf.writeBytes(str2.getBytes());
        // 创建一个复合缓冲区
        CompositeByteBuf compositeByteBuf = Unpooled.compositeBuffer(10);
        compositeByteBuf.addComponents(heapBuf, directBuf);
        // 检查是否支持支撑数组,发现并不支持
        if (!compositeByteBuf.hasArray()) {
            for (ByteBuf buf : compositeByteBuf) {
                // 第一个字节偏移量
                int offset = buf.readerIndex();
                // 总共数据长度
                int length = buf.readableBytes();
                byte[] bytes = new byte[length];
                // 不支持访问支撑数组,需要将内容复制到堆内存中,即 bytes 数组中,才可以进行访问
                buf.getBytes(offset, bytes);
                printByteBuffer(bytes, offset, length);
            }
        }
    }
    
    private static void printByteBuffer(byte[] array, int offset, int length) {
        System.out.println("array:" + array);
        System.out.println("array->String:" + new String(array));
        System.out.println("offset:" + offset);
        System.out.println("len:" + length);
    }
    /**输出**/
    array:[B@4f8e5cde
    array->String:hi
    offset:0
    len:2
    array:[B@504bae78
    array->String:nihao
    offset:0
    len:5
    

Netty 中 ByteBuf 如何分配?有池化的操作吗?

答:

ByteBuf 的分配接口定义在了 ByteBufAllocator 中,他的直接抽象类是 AbstractByteBufAllocator,而 AbstractByteBufAllocator 有两种实现:PooledByteBufAllocatorUnpooledByteBufAllocator

在这里插入图片描述

  • PooledByteBufAllocator 提供了池化的操作,将 ByteBuf 实例放入池中,提升了性能,将内存碎片化减到了最小UnpooledByteBufAllocator。(这个实现采用了一种内存分配的高效策略,成为 jemalloc,已经被好几种现代操作系统所采用)
  • UnpooledByteBufAllocator 在每次创建缓冲区时,都会返回一个新的 ByteBuf 实例,这些实例由 JVM 负责 gc 回收

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/194040.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot详解

一、介绍 Spring Boot 是一个基于 Spring 框架的开源框架,用于构建微服务和 Web 应用程序。它可以帮助开发者轻松创建独立的、基于 Spring 的应用程序,并在较短的时间内完成项目的开发。 二、核心 1. 约定大于配置 Spring Boot 通过自动化配置、约定优…

【C++】静态成员

静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员。 静态成员分为: 静态成员变量 所有对象共享同一份数据在编译阶段分配内存类内声明,类外初始化 静态成员函数 所有对象共享同一个函数静态成员函数只能访问静态成员变量 …

Java制作“简易王者荣耀”小游戏

第一步是创建项目 项目名自拟 第二部创建个包名 来规范class 然后是创建类 GameFrame 运行类 package com.sxt;import java.awt.Graphics; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; im…

Flask 运用Xterm实现交互终端

Xterm是一个基于X Window System的终端仿真器(Terminal Emulator)。Xterm最初由MIT开发,它允许用户在X Window环境下运行文本终端程序。Xterm提供了一个图形界面终端,使用户能够在图形桌面环境中运行命令行程序。而xterm.js是一个…

使用STM32和蓝牙模块进行无线数据传输的实践

无线数据传输在现代通信领域中具有重要的地位,而蓝牙技术是一种常用的无线数据传输技术。本文介绍了如何使用STM32微控制器和蓝牙模块实现无线数据传输的方案,包括硬件设计、蓝牙模块配置、数据发送和接收等步骤,并给出相应的代码示例。 一、…

学习知识回顾随笔

文章目录 如何远程连接MySQL数据库1.创建用户来运行,此用户从任何主机连接到mysql数据库2.使用IP地址来访问MySQL数据库 如何远程访问Django项目Web应用什么是Web应用应用程序的两种模式Web应用程序的优缺点 HTTP协议(超文本传输协议)简介HTT…

使用C#和HtmlAgilityPack打造强大的Snapchat视频爬虫

概述 Snapchat作为一款备受欢迎的社交媒体应用,允许用户分享照片和视频。然而,由于其特有的内容自动消失特性,爬虫开发面临一些挑战。本文将详细介绍如何巧妙运用C#和HtmlAgilityPack库,构建一个高效的Snapchat视频爬虫。该爬虫能…

Nginx Openresty通过Lua+Redis 实现动态封禁IP

需求 为了封禁某些爬虫或者恶意用户对服务器的请求,我们需要建立一个动态的 IP 黑名单。对于黑名单中的 IP ,我们将拒绝提供服务。并且可以设置封禁失效时间 环境准备 linux version: centos7 / ubuntu 等 redis version: 5.0.5 nginx version: nginx…

高端影像仪:打破微小产品测量局限

在现代工业生产中,影像仪以CCD数位影像为基石,将计算机屏幕测量技术与空间几何运算的能力融为一体,可以用于测量微小产品的各种尺寸和形状,为生产过程中的质量控制提供重要的参考依据。 影像仪产品内置高精度光学电动双倍镜头&am…

竞赛选题 题目:基于大数据的用户画像分析系统 数据分析 开题

文章目录 1 前言2 用户画像分析概述2.1 用户画像构建的相关技术2.2 标签体系2.3 标签优先级 3 实站 - 百货商场用户画像描述与价值分析3.1 数据格式3.2 数据预处理3.3 会员年龄构成3.4 订单占比 消费画像3.5 季度偏好画像3.6 会员用户画像与特征3.6.1 构建会员用户业务特征标签…

百度人工智能培训第一天笔记

参加了百度人工智能初步培训,主要是了解一下现在人工智能的基本情况,以便后续看可以参与一些啥? 下面就有关培训做一些记录,以便后续可以继续学习。 一、理论基础部分 二、实际操作部分 主要学习的百度人工智能平台如下&#xf…

Go——三、运算符以及流程控制

Go 一、Go语言运算符1、算数运算符2、关系运算符3、逻辑运算符4、位运算符5、赋值运算符6、其他运算符7、运算符优先级 二、Go的流程控制1、if else2、for 循环结构3、for range(键值循环)4、switch case5、break:跳出循环6、go:跳…

IDEA编译器技巧-提示词忽略大小写

IDEA编译器技巧-提示词忽略大小写 写代码时,每次创建对象都要按住 Shift 字母 做大写开头, 废手, 下面通过编译器配置解放Shift 键 setting -> Editor -> General -> Code Completion -> Match case 把这个√去掉, 创建对象就不需要再按住 Shift 键 示例: 1.…

Android Termux SFTP如何实现远程文件传输

文章目录 1. 安装openSSH2. 安装cpolar3. 远程SFTP连接配置4. 远程SFTP访问4. 配置固定远程连接地址 SFTP(SSH File Transfer Protocol)是一种基于SSH(Secure Shell)安全协议的文件传输协议。与FTP协议相比,SFTP使用了…

Linux静态库,共享库,计算机基础知识

1.库文件: 1).库文件库是一组预先编译好的方法的集合;Linux系统存储库的位置一般在/lib 和 /usr/lib (64位系统/usr/lib64)库的头文件放在/usr/include 2).库的分类 静态库:libxxx.a(命名规则) 共享库:libxxx.so(命名规则) 3).准备文件: //add.c int add(int x,int y) { retu…

设计模式—迪米特原则(LOD)

1.背景 1987年秋天由美国Northeastern University的Ian Holland提出,被UML的创始者之一Booch等普及。后来,因为在经典著作《 The Pragmatic Programmer》而广为人知。 2.概念 迪米特法则(Law of Demeter)又叫作最少知识原则&…

免费部署开源大模型

参考:【大模型-第一篇】在阿里云上部署ChatGLM3-CSDN博客 ChatGLM 是一个开源的、支持中英双语的对话语言模型,由智谱 AI 和清华大学 KEG 实验室联合发布,基于 General Language Model (GLM) 架构,具有 62 亿参数。ChatGLM3-6B 更…

Fluent热辐射壁面设置

对于固体壁面,可分为: 内部面外部面 外部面,若需要考虑外部热辐射的影响,需要将类型改为“mixed”或者“radiation”类型,并设置外部的发射率。 内部面通常为“wall”和“wall-shadow”的配对形式。 对于两侧均是透明…

了解FastSam:一个通用分割模型(草记)

想尝试这个FastSam的部署,但至今还没跑通,一个问题能带出一片问题,感觉挺心情挺郁闷的。后来和学长交流的时候,说那就是学少了,没必要急着将跑通它作为目的。也很有道理,这个任务还不太适合我当前的水平&am…

vscode Markdown 预览样式美化多方案推荐

优雅的使用 vscode写 Markdown,预览样式美化 1 介绍 我已经习惯使用 vscode 写 markdown。不是很喜欢他的 markdown 样式,尤其是代码块高亮的样式。当然用 vscode 大家基本上都会选择安装一个Markdown-preview-enhanced的插件,这个插件的确…