DPDK入门(环境搭建以及小demo)

news2024/11/14 21:15:03

文章目录

  • 零、从`0`开始配置`dpdk`环境的虚拟机
  • 一、`dpdk`的编译`usertool/dpdk-setup.sh`
  • 二、`dpdk`需要什么配置来支持
    • 1.多队列网卡
    • 2.巨页
  • 三、解析接收网络数据的过程经历了什么
    • 1.物理网卡
    • 2.`NIC`
    • 3.内核协议栈
    • 4.标准接口层`Posix API`
    • 5. 应用层
    • 上述过程发生的拷贝
  • 四、`DPDK`介绍
    • 基于上述接收网络数据流程`dpdk`做的事
    • `dpdk`如何组织映射的数据
      • `Huge Page`
    • `dpdk`优化了什么
    • `KNI`机制
    • `DPDK`的技术边界
      • `DPDK`能做什么
  • 五、`DPDK`该怎么学
  • 六、`coding`
    • `rte_eal_init(argc, argv)`初始化`dpdk`应用
    • `rte_pktmbuf_pool_create`创建
    • 对网口的配置
    • 接受数据
      • 使用`API`接受数据
      • 循环遍历解析所有接受到的包
  • **关于`dpdk`无法接收来自主机的数据解决**
    • 重启虚拟机后需要做的事

零、从0开始配置dpdk环境的虚拟机

  • 外部配置

    • 配置网卡

      • 初始网卡选择桥接模式作为dpdk运行的网卡,添加第二张网卡NAT模式用于ssh连接

      • 内存与CPU核数选择

        • 内存选择8g以上,核数选择8核以上
    • 修改源文件让网卡支持多队列

      • 修改虚拟机的vmx文件,修改ethernet0.virtualDev = "e1000"的值并添加一行
      ethernet0.virtualDev = "vmxnet3"
      ethernet0.wakeOnPcktRcv = "TRUE"
      
  • 内部配置

    • 配置网卡

      • 在安装``ubunt_userver时,存在多个网卡时需要选择默认网关网卡,这里选择用于ssh连接网卡ens33`

      • ens160是多队列网卡,配置其静态ip地址,在/etc/network/interface追加下面行

        auto ens160
        iface ens160 inet static
        address 10.17.43.34
        netmask 255.255.0.0
        

        ip需要根据主机的ip地址的网段和掩码一致,因为这是桥接模式,第二章nat网卡直接使用dhcp自动获取ip网关dns服务器即可

        使用route -n可以查看默认网关

    • 修改系统启动参数

      • 修改etc/default/grub文件

        GRUB_CMDLINE_LINUX_DEFAULT=""
        GRUB_CMDLINE_LINUX=""
        >>>>修改后
        GRUB_CMDLINE_LINUX_DEFAULT="quiet"
        GRUB_CMDLINE_LINUX="find_preseed=/preseed.cfg noprompt net.ifnames=0 biosdevname=0 default_hugepages=1G hugepagesz=2M hugepages=1024 isolCPUs=0-2"
        

        修改后update-grubreboot会发现网卡名字变为了eth*,此时修改/etc/network/interfaces文件

        • eth0对应第一张也就是桥接模式的网卡,就替换ens160
        • eth1替换ens33

一、dpdk的编译usertool/dpdk-setup.sh

  • 下载dpdk-19.08.2,在dpdk-stable-19.08.2文件夹下执行./usertools/dpdk-setup.sh

  • 选择不带appx86_64-native-linux-gcc[39],因为它可以改源码

  • 设置运行时环境变量

    export RTE_SDK=/home/ljq/share/module/dpdk-stable-19.08.2/
    
  • 设置运行时环境的目标

    export RTE_TARGET=x86_64-native-linux-gcc
    
  • ./usertools/dpdk-setup.sh选择[43] or [44]插入IGB_UIO模块 or插入V

  • 选择[45]插入KNI模块

  • 选择[46] or [47]巨页的配置

    • 46代表采用no numa方式管理多内存编号,47代表采用numa方式管理多内存编号

      numa表示不是同一的编码方式,每个内存块都从索引0开始,no-numa表示同一编码方式,内存块之间的索引是连着的

    • 512来设置1g的巨页

  • 选择[49] or [50]

    • 把对应网卡的绑定设备绑定在哪个模块上[49]->UIO [50]->VFIO

    • 两者选一个 我选49

      • 接着输入PCI地址来绑定IGB UIO

        找到eth0对应的行,输入其前面的数字字符串 我的是0000:03:00.0

        回车后会警告:

        Warning: routing table indicates that interface 0000:03:00.0 is active. Not modifying OK,意思是还在工作中 没有修改成功

        我们要给他down掉,就是不让对应的NIC接收数据,让dpdk去绑定这个网卡去截获,网卡的数据就不会往内核里面走了

        ifconfig eth0 down

        再次选择49,输入0000:03:00.0后绑定成功

        此时ifconfig是不存在eth0,也就是说明此时eth0对应的NIC不会再去接管他了,之后所有数据就是走到dpdk里面了

编译前需要安装的

sudo apt-get install libnuma-dev libpcap-dev make

dpdk接管网卡的两种方式

  • 通用型IO
  • 虚拟IO

注意有可能45出会出现错误,此时使用grep CONFIG_RTE_KNI /boot/config-$(uname -r)查看CONFIG_RTE_KNI是否被设置为了m或者y,如果没有则需要手动添加进去

二、dpdk需要什么配置来支持

1.多队列网卡

dpdk要指定用哪一个队列来接收数据

2.巨页

三、解析接收网络数据的过程经历了什么

1.物理网卡

  • 物理网卡接收(vmware的网络适配器就是一个网卡,是vmware模拟的)
  • 物理网卡是光信号或者电信号与数字信号的相互转换

2.NIC

  • 接收后每个网卡都会配对的有一个网络适配器(NIC
    • 问题,NIC什么数据结构存?
    • 使用ifconfig就是查看NIC的数量以及相关信息
    • 网卡每来一帧数据NIC都会将它组织成sk_buff(其中有很多指针,指向数据包中的各个层的头部),发送给协议栈,协议栈就解析其各个头

3.内核协议栈

  • NIC把数据抛给内核协议栈,协议栈解析其sk_buff中指向的各个头,注意这个协议栈是所有网卡共用的
    • 协议栈与NIC驱动的数据交互是怎样的
      • 网卡每来一帧数据NIC都会将它组织成sk_buff(其中有很多指针,指向数据包中的各个层的头部),发送给协议栈,协议栈就解析其各个头

4.标准接口层Posix API

  • 标准接口层调用各种网络系统调用

5. 应用层

应用层就接收到了…

上述过程发生的拷贝

  1. 网卡数据拷贝到NIC,组织出sk_buff

  2. APP调用recv..将数据从内核态拷贝到用户态

  3. 上述操作需要CPU的参与

四、DPDK介绍

基于上述接收网络数据流程dpdk做的事

  • 把网卡通过一种映射的方式,把网卡接收数据的存储空间映射到用户态的内存空间中,

    这其中没有拷贝,是通过DMA的方式,直接网络适配器与硬盘驱动器与内存交互

  • dpdk主要做的事:把网卡的数据快速转移到用户态内存里

dpdk如何组织映射的数据

Huge Page

  • 正常的内存操作,一个页4k,假设一秒钟来了1G的数据,那么4k的页划分的包就为256x1024,太多了,于是dpdk采用巨页

dpdk优化了什么

threadCPU的亲缘性

  • 某一线程只在同一个CPU上运行

KNI机制

dpdk只想处理一种协议,其他协议还是通过内核协议栈来处理

  • dpdk提供了一种方式,将不需要的数据写入到内核协议栈,内核网络接口(Kernel Network Interface<kni>)

DPDK的技术边界

dpdk处理数据时是跨过了NIC这一层,在NIC接收数据前就截获了数据,与NIC平级,改变了数据流程

DPDK能做什么

  1. 路由器、SDN网络定制开发
  2. 网络协议栈
  3. 防火墙,防ddos攻击
    1. 接收数据,检测异常数据
  4. VPN
    1. 直接往原始数据中加入vxline或加上隧道技术再从网卡中发送出去

五、DPDK该怎么学

环境搭建完后该做的事

  • coding,代码可控
    • 实现一个协议栈(eth,ip,arp,icmp,tcp,udp)
    • posix api, epoll的实现
  • 协议栈是与dpdk相生相辅
  • 行业的应用
    • 三层网络层的vpp
    • 二层传输层考虑ovs
    • 负载均衡dpvs
    • 发包工具pktgen
  • 1-2款上线的产品。。。

六、coding

rte_eal_init(argc, argv)初始化dpdk应用

rte_pktmbuf_pool_create创建

rte_pktmbuf_pool_create(
	const char * name,
    unsigned int n,  // 初始化mbufpoll池能放多少个mbuf
    unsigned int cache_size,  // 0
    uint16_t priv_size,  // 0
    unit16_t data_room_size,
    int socket_id  // 设置为一个全局的一个变量per_lcore_socket_id
);
// 返回一个rte_mempoll结构体
  • 名字中的mbuf就是内核中的sk_buf
  • namePacket Buffer 池的名称,可以是任何字符串,建议使用有意义的名称。
  • nPacket Buffer 池中 Packet Buffer 的数量,建议设置为大于等于 1024
  • cache_sizePacket Buffer 池中的本地缓存大小,可以根据使用场景进行调整,建议设置为 Packet Buffer 数量的1/8左右。
  • priv_sizePacket Buffer 中每个 Packet Buffer 的私有数据大小,如果不需要私有数据,则可以设置为 0
  • data_room_sizePacket Buffer 中数据区域的大小,即可以存储数据包的空间大小,建议设置为 2048 或更大。
  • socket_id:用于分配内存的 NUMA 节点编号,建议设置为套接字绑定的CPU所在的NUMA节点编号。

对网口的配置

TCP/IP网络中,当一个网络设备接收到来自其他设备的数据包时,就会触发RX操作,将数据包解析并交给上层协议或应用程序

tx与rx是什么分别用在什么地方

txqueue主要用于管理应用程序待发送的数据包,当应用程序需要向网络中发送数据时,首先将其封装成一个数据包,并添加到txqueue中。

rxqueue主要用于管理已经从网络中接收到的数据包,当网络中有数据包到达时,DPDK会将其添加到rxqueue中,应用程序可以从rxqueue中取出数据包并进行进一步的处理。

	// setup
	uint16_t nb_rx_queues = 1;
	uint16_t nb_tx_queues = 0;
	const struct rte_eth_conf port_conf_default = {
		.rxmode = {.max_rx_pkt_len = RTE_ETHER_MAX_LEN }
	};
	
	rte_eth_dev_configure(gDpdkPortId, 
                          nb_rx_queues, 
                          nb_tx_queues, 
                          &port_conf_default); 

	// 设置第gDpdkPortId个绑定网口的信息,使用了索引为0对应的rx队列,设置了rx队列的大小为128,使用mbuf_pool来存储接收队列缓存
	rte_eth_rx_queue_setup(gDpdkPortId,  // 设置第gDpdkPortId个绑定网口的信息
                           0,   		 // 使用了索引为0对应的rx队列
                           128,			 // 设置了rx队列的大小为128
                           rte_eth_dev_socket_id(gDpdkPortId), 
                           NULL, 
                           mbuf_pool);	 // 使用mbuf_pool来存储接收队列缓存
	// 
	rte_eth_dev_start(gDpdkPortId);

	// disable
	//rte_eth_promiscuous_enable(gDpdkPortId); //

  • rte_eth_dev_configureAPI介绍

    ret_eth_dev_configure(
    	unit16_t port_id,  //网口 nic 的id是什么
        unit16_t nb_rx_q,  // rx队列 ,对应索引  0表示使用第一个
        unit16_t nb_tx_q,  
        const struct rte_eth_conf* dev_conf  // 配置信息  每个包的长度
    );
    
    • port_id:以太网设备的端口 ID。
    • nb_rx_queue:用于接收数据包的 RX 队列数量。
    • nb_tx_queue:用于发送数据包的 TX 队列数量。
    • eth_conf:一个结构体,包含了以太网设备的配置信息,如 CRC 校验、硬件 RSS 散列、速率控制,以及杂项配置等。
  • rte_eth_rx_queue_setup API介绍

    int rte_eth_rx_queue_setup(
        uint16_t port_id,      // 要绑定的网口索引号 0代表使用第一个网口
        uint16_t rx_queue_id,  // 要绑定的队列的索引,0代表绑定第一个rx队列
    	uint16_t nb_rx_desc,   // 指定队列可以装多少mbuf
        unsigned int socket_id,
    	const struct rte_eth_rxconf *rx_conf,
    	struct rte_mempool *mb_pool
    );
    
    • port_id:以太网设备的端口 ID。
    • rx_queue_id:将要创建的接收队列的队列号。
    • nb_rx_desc:用于网卡接收队列的缓存区描述符数量,可以简单理解为接收队列的缓存容量。(是网卡上面的rx_queue_id对应id的接收队列的大小,前面mbuf_pool内存池的大小就是用来接收这个队列中的节点,所以这个内存池的大小肯定要比rx队列大小大)
    • socket_id:用于分配和管理内存资源的 NUMA 节点 ID,一般使用 rte_socket_id() 函数获取。
    • rx_conf:用于指定接收队列的配置信息,如 RSS 散列、哈希过滤器和 Ptype 解析等特性。如果不需要使用这些特性,可以将该参数设置为 NULL
    • mb_pool:用于存储接收队列缓存的内存池指针。

接受数据

    while(1){
        //..后面的代码都在这个里面
    }

使用API接受数据

		struct rte_mbuf *mbufs[MBUF_SIZE];  // 32
		unsigned num_recvd = rte_eth_rx_burst(
            gDpdkPortId,   // 绑定的网口
            0,             // rx队列索引
            mbufs, 
            MBUF_SIZE  // 设置的32
        );
		if (num_recvd > MBUF_SIZE) {
			rte_exit(EXIT_FAILURE, "rte_eth_rx_burst Error\n");
		}
  • rte_eth_rx_burst

    uint16_t rte_eth_rx_burst(uint16_t port_id, 
                              uint16_t queue_id,
                              struct rte_mbuf **rx_pkts,  // 传出参数
                              const uint16_t nb_pkts
                           	  );
    // 不需要考虑释放  在内存池中直接将对应id取出来直接用
    
    • port_id:以太网设备的端口 ID
    • queue_id:用于接收数据包的 RX 队列 ID
    • rx_pkts:指向 rte_mbuf 结构体指针的数组,用于存储接收到的数据包。
    • nb_pkts:要读取的最大数据包数量。

循环遍历解析所有接受到的包

unsigned i = 0;
for (i = 0;i < num_recvd;i ++) {
    // 宏函数
    struct rte_ether_hdr *ehdr = rte_pktmbuf_mtod(
        mbufs[i], 
        struct rte_ether_hdr *
    );
    if (ehdr->ether_type != rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)) {
        continue;
    }

    struct rte_ipv4_hdr *iphdr = rte_pktmbuf_mtod_offset(
        mbufs[i], 
        struct rte_ipv4_hdr *, 
        sizeof(struct rte_ether_hdr)
    );

    if (iphdr->next_proto_id == IPPROTO_UDP) {

        struct rte_udp_hdr* udphdr = (struct rte_udp_hdr*)(iphdr + 1);  // 加上IP头得到udp头
        uint16_t length = udphdr->dgram_len;
        *((char*) udphdr + length - 1) = '\0';
        printf("udp: %s\n",  (char*)(udphdr+1));
    }
}
  • rte_pktmbuf_mtod 是一个宏,而不是一个函数。在 DPDKrte_mbuf.h 文件中,可以看到 rte_pktmbuf_mtod 的定义如下:

    #define rte_pktmbuf_mtod(m, t)  ((t)((char *)((m)->buf_addr) + (m)->data_off))
    

    这个宏的实现使用了强制类型转换,其目的是将缓冲区中数据的地址转换为用户指定的数据类型 t 的指针,从而方便用户访问和处理接收到的数据包。需要注意的是,在使用 rte_pktmbuf_mtod 宏时,应当确保传入的参数合法,并且传入的数据类型和数据包的格式相符,否则可能会导致程序错误。

设置arp静态映射

arp静态映射 就可以用网络调试工具调试了

注意设置的ip地址是要与本机网卡ip地址是同一个网段

arp -s 10.17.31.80 00-0C-29-AF-77-5C

arp -d 10.17.31.80

# The ARP entry addition failed: Access is denied

netsh i i show in  # 查看网络接口的索引号

netsh -c i i add neighbors 18 10.17.31.80 00-0C-29-AF-77-5C

netsh -c "i i" delete neighbors 1

关于dpdk无法接收来自主机的数据解决

  • 保证绑定网卡前主机可以ping通虚拟机的eth0的桥接网卡

  • eth0ip要在主机上静态绑定eth0mac请添加图片描述

重启虚拟机后需要做的事

  • 查看主机ip是否改变(连接不同的网络都会改变)
    • 如果改变了就重新设置/etc/network/interfaces文件,设置eth的静态ip,需要与主机ip为同一网段即可

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Github采用Http Push失败

Github采用Http Push失败 Github的密码凭证从2021年起开始就不能用了&#xff0c;现在采用http去push代码时候提示输入的密码要换成令牌&#xff08;token&#xff09;才可以。 如何在Github上生成自己的令牌呢&#xff1f; &#xff08;1&#xff09;简单来说就是将原来输入…

Linux搭建GitLab私有仓库,并内网穿透实现公网访问

文章目录前言1. 下载Gitlab2. 安装Gitlab3. 启动Gitlab4. 安装cpolar5. 创建隧道配置访问地址6. 固定GitLab访问地址6.1 保留二级子域名6.2 配置二级子域名7. 测试访问二级子域名前言 GitLab 是一个用于仓库管理系统的开源项目&#xff0c;使用Git作为代码管理工具&#xff0c…

游戏运营专员的职责有哪些?提高游戏收入的关键是什么?

游戏运营是将一款游戏平台推入市场&#xff0c;通过对平台的运作&#xff0c;使用户从接触、认识、再到了解实际线上的一种操作、最终成为这款游戏平台的忠实玩家的这一过程。同时通过一系列的营销手段达到提高线上人数&#xff0c;刺激消费增长利润的目的。 游戏运营专员的职…

4.3 协方差及相关系数、矩

学习目标&#xff1a; 我正在学习协方差、相关系数和矩&#xff0c;我会采取以下措施&#xff1a; 理解基本概念&#xff1a;首先&#xff0c;我会努力理解协方差、相关系数和矩的基本概念。我会查阅参考资料&#xff0c;例如课本或在线教程&#xff0c;以便深入了解这些概念…

Unity设计模式—子类沙盒

Unity设计模式—子类沙盒 一个基类定义了一个抽象的沙河方法和一些预定义的操作集合。通过将它们设置为受保护的状态已确定它们仅供子类使用。每个派生的沙盒子类根据父类提供的操作来实现沙盒操作。 子类沙盒的名字比较生僻&#xff0c;其实内容非常常见&#xff0c;平常用的很…

警惕,3月20日WOS目录更新,50本SCI/SSCI被剔除,这个出版社多达18本

2023年3月SCI、SSCI期刊目录更新 2023年3月20日&#xff0c;Web of Science核心期刊目录再次更新&#xff01;此次2023年3月SCIE & SSCI期刊目录更新&#xff0c;与上次更新&#xff08;2023年2月&#xff09;相比&#xff0c;共有50本期刊被剔除出SCIE & SSCI期刊目录…

香橙派4LTS和树莓派4B构建K8S集群实践之一:K8S安装

目录 1. 说明 1.1 软硬件环境 1.2 设计目标 2 实现 2.1 准备工作 - 香橙派 (k8s-master-1) - 树莓派 (k8s-node-1) - 两派都要干的事 2.2 containerd 安装与设置 2.3 安装 3 遇到的问题 3.1 k8s-master-1 3.2 k8s-node-1 4 相关命令 5 Tips 6 参考 1. 说明 …

【论文笔记】Deformable Convolutional Networks

1.介绍 1.1. 提出DCN的原因 卷积神经网络&#xff08;CNNs&#xff09;由于其固定几何结构局限了模型几何变换。 1.2.本文核心贡献&#xff1a;提出了两种新模块 deformable convolution 和 deformable RoI pooling 第一种是可变形卷积。它将2D偏移添加到标准卷积中的规则网…

【点云概述】什么是点云、来源、种类、特点、处理?

文章目录 一、什么是点云二、点云的来源三、点云的种类四、点云的特点五、点云的处理一、什么是点云 点云(point cloud)是空间中点的数据集,可以表示三维形状或对象,通常由三维扫描仪获取。点云中每个点的位置都由一组笛卡尔坐标 ( X , Y , Z ) (X, Y, Z) (X,Y,Z)描述,有…

【C++】4. 重载函数

文章目录 前言一、函数重载1.1 重载的条件1.2 函数名修饰 前言 自然语言中&#xff0c;一个词可以有多重含义&#xff0c;人们可以通过上下文来判断该词真实的含义&#xff0c;即该词被重载了。比如&#xff1a;以前有一个笑话&#xff0c;国有两个体育项目大家根本不用看&…

双目三维测距(python)

文章目录 1. 双目检测1.1 调用相机1.2 分割画面 2. 双目标定2.1 相机标定2.2 获取参数 3. 双目测距3.1 立体校正3.1.1 校正目的3.1.2 校正方法3.1.2 相关代码 3.2 立体匹配和视差计算3.3 深度计算3.4 注意事项 4. 完整代码 代码打包下载&#xff1a; 链接1&#xff1a;https://…

Spring MVC 的调用(12)

目录 SpringMVC流程 源码分析 第一步:用户发起请求到前端控制器&#xff08;DispatcherServlet&#xff09; 第二步&#xff1a;前端控制器请求处理器映射器&#xff08;HandlerMappering&#xff09;去查找处理器&#xff08;Handle&#xff09;&#xff1a;通过xml配置或者…

LeetCode:28. 找出字符串中第一个匹配项的下标 ——【1、理解 KMP 算法】

&#x1f34e;道阻且长&#xff0c;行则将至。&#x1f353; &#x1f33b;算法&#xff0c;不如说它是一种思考方式&#x1f340;算法专栏&#xff1a; &#x1f449;&#x1f3fb;123 目录一、&#x1f331;[28. 找出字符串中第一个匹配项的下标](https://leetcode.cn/proble…

synchronized 的 monitor 机制

synchronized 的 monitor 机制 前言 本文基于 jdk 8 编写。author JellyfishMIX - github / blog.jellyfishmix.comLICENSE GPL-2.0 monitor monitor 是 synchronized 中用以实现线程之间的互斥与协作的主要手段&#xff0c;它可以看成是对象或者 class 持有的锁。每一个对象…

十六、市场活动:查看市场活动明细(一)

功能需求 点击市场活动名称链接,跳转到明细页面,查看市场活动明细 -市场活动的基本信息 -市场活动下所有的备注信息 功能分析 流程图 代码实现 一、ActivityMapper 1.ActivityMapper接口 /*** 点击名称&#xff0c;查看市场详细*/Activity selectActivityForDetailById(Stri…

相量的加减乘除计算

相量的加减乘除计算 矢量是物理学中的术语&#xff0c;是指具有大小&#xff08;magnitude&#xff09;和方向的量。如速度、加速度、力等等就是这样的量。向量是数学中的术语&#xff0c;也称为欧几里得向量、几何向量、矢量。与向量对应的量叫做数量&#xff0c;在物理学中称…

二叉树基础概念

1.二叉树种类 1.1 满二叉树 满二叉树&#xff1a;如果一棵二叉树只有度为 0 0 0 的结点和度为 2 2 2 的结点&#xff0c;并且度为0的结点在同一层上&#xff0c;则这棵二叉树为满二叉树。 如图所示&#xff1a; 这棵二叉树为满二叉树&#xff0c;也可以说深度为 k k k&…

自动驾驶企业面临哪些数据安全挑战?

近期&#xff0c;“特斯拉员工被曝私下分享用户隐私”不可避免地成了新闻热点&#xff0c;据说连马斯克也不能幸免。 据相关媒体报道&#xff0c;9名前特斯拉员工爆料在2019年至2022年期间&#xff0c;特斯拉员工通过内部消息系统私下分享了一些车主车载摄像头记录的隐私视频和…

JVM|为对象分配内存空间的流程

1. Eden是否能装下新对象&#xff1f; 1.1 如果可以&#xff0c;则装入新对象&#xff1b; 1.2 如果不可以&#xff0c;则发动minor gc&#xff1b; 2. minor gc后Eden空间是否能装下新对象&#xff1f; 2.1 如果可以&#xff0c;装入新对象&#xff1b; 2.2 如果不可以&#…

长安链引入全新身份认证体系IBC:突破公钥不可理解的限制

近日&#xff0c;未来区块链与隐私计算高精尖创新中心研究团队为长安链带来了一套基于国密SM9算法的全新标识身份认证体系IBC&#xff08;Identity-Based Cryptography&#xff09;。该项成果融合标识密码和现代身份管理体系&#xff0c;打破区块链数字身份监管难、管理难、联通…