DPDK源码分析之(1)libmbuf模块

news2025/1/1 14:56:00

DPDK源码分析之(1)libmbuf模块

Author:OnceDay Date:2024年7月2日

漫漫长路,有人对你笑过嘛…

全系列文档可参考专栏:源码分析_Once-Day的博客-CSDN博客

参考文档:

  • DPDK download
  • Getting Started Guide for Linux — documentation (dpdk.org)
  • Sample Applications User Guides — documentation (dpdk.org)
  • 14. Mbuf Library — Data Plane Development Kit 24.07.0-rc1 documentation (dpdk.org)
  • dpdk/lib/mbuf at main · DPDK/dpdk · GitHub
  • TCP/IP Illustrated, Volume 2: The Implementation (kohala.com)

文章目录

      • DPDK源码分析之(1)libmbuf模块
        • 1. 概述
          • 1.1 mbuf介绍
          • 1.2 mbuf设计概念
          • 1.3 mbuf使用mempool
          • 1.4 mbuf对象池构造过程
        • 2. mbuf对象定义
          • 2.1 mbuf数据结构
          • 2.3 mbuf操作函数定义

1. 概述
1.1 mbuf介绍

mbuf(消息缓冲区)库提供了分配和释放缓冲区(mbufs)的功能,这些缓冲区可以被DPDK应用程序用来存储消息。消息缓冲区存储在一个称为mempool(内存池)的结构中,而这个内存池是通过Mempool库来管理的。

通常情况下,rte_mbuf结构体用于承载网络数据包缓冲区,但实际上它可以存储任何类型的数据(例如控制数据、事件等)。为了提高性能,rte_mbuf头部结构被设计得尽可能小,目前只使用了两个缓存行(cache line),并且最常用的字段被放在第一个缓存行中。

  • 内存池(Mempool)管理:内存池库通过预先分配大量固定大小的内存对象(如mbufs),来提高内存分配和释放的效率。这种方法避免了频繁的动态内存分配,从而减少了内存碎片和分配开销。

  • 缓存行优化:缓存行是CPU缓存中存储数据的最小单位。将频繁访问的数据字段放在同一个缓存行中,可以减少CPU缓存未命中(cache miss)的次数,从而提高数据访问速度。

  • 灵活性rte_mbuf不仅能承载网络数据包,还能用于其他用途,如存储控制信息或事件消息。这使得它在各种DPDK应用程序中都能发挥作用。

1.2 mbuf设计概念

为了存储数据包(包括协议头部),考虑了两种方法:

  • 在单个内存缓冲区中嵌入元数据结构,后面跟一个固定大小的区域用于存储数据包。优点是只需要一次操作即可分配/释放整个数据包的内存表示。
  • 使用独立的内存缓冲区分别存储元数据结构和数据包。更灵活,允许元数据结构的分配与数据包缓冲区的分配完全分离。

DPDK选择了第一种方法,元数据包含控制信息,如消息类型、长度、数据起始位置的偏移量以及指向其他mbuf结构的指针,从而实现mbuf链的功能

用于承载网络数据包的消息缓冲区可以处理mbuf链,即需要多个缓冲区来保存完整数据包的情况。例如,巨型帧(jumbo frames)由多个通过next字段链接在一起的mbufs组成。

对于新分配的mbuf,数据的起始位置位于缓冲区开始后RTE_PKTMBUF_HEADROOM字节处,该位置是缓存对齐的。消息缓冲区可以用于在系统的不同实体之间传递控制信息、数据包、事件等。

消息缓冲区还可以使用其缓冲区指针指向其他消息缓冲区的数据部分或其他结构,称为间接mbuf,类似于上面的第二种方法

总结mbuf的设计

  1. 单一内存缓冲区,DPDK选择了在单一内存缓冲区中嵌入元数据结构的设计,简化了分配和释放的操作。
  2. 元数据包含控制信息,元数据结构中包含消息类型、长度、数据起始位置的偏移量以及用于缓冲区链的指针。
  3. 缓冲区链,支持缓冲区链,允许多个mbufs链接在一起,特别适用于需要多个缓冲区来保存完整数据包的情况(如巨型帧)。
  4. 缓存对齐,新分配的mbuf的数据起始位置经过缓存对齐,位于RTE_PKTMBUF_HEADROOM字节之后,优化了性能。
  5. 多用途,消息缓冲区不仅用于传输数据包,还可以在系统中传递控制信息、事件等,具有很高的灵活性。
  6. 完全标准的mbuf操作函数集合,遵循常见标准和原则的mbuf操作函数实现。

下面是单个段组成的mbuf,一个mbuf持有整个报文的数据

在这里插入图片描述

下面是多个段组成的mbuf,一个主mbuf+多个子mbuf共同持有整个报文的数据

在这里插入图片描述

mbuf的构成如下:

| rte_mbuf | ==> rte_mbuf priv size<== | rte_pktmbuf_headroom |     data(Packet data)        | 
|     ==>    struct mbuf     <==       ↓     Headroom(128)    |     dataroom(2176)           |
								   buf.addr    ---->  data_offset
									                          |       MBUF_RX_SIZE=2176      |

这是一个带有私有应用数据的mbuf,其默认headroom是128字节,数据空间是2176字节,rte_mbuf是控制元数据,两个cache line共128字节。

1.3 mbuf使用mempool

mbuf缓冲区管理器(Buffer Manager)使用内存池库(Mempool Library)来分配缓冲区。因此,它确保数据包头在不同的通道和内存组(ranks)之间以最佳方式交错排列,以便L3缓存处理。

一个mbuf包含一个字段,用于指示其来源的内存池。当调用rte_pktmbuf_free(m)时,mbuf会返回到其原始的内存池中。

(1) 内存池概述

  • 内存池是一种用于管理固定大小对象集合的高效机制,专门设计用于减少动态内存分配和释放的开销。
  • 在DPDK中,内存池库(Mempool Library)负责管理这些内存池,提供快速的对象分配和释放功能。

(2) 内存池的创建和使用

  • 内存池在初始化时分配一组固定大小的内存块。这些内存块可以被反复使用,以提高性能和减少内存碎片。
  • 应用程序通过调用rte_mempool_create()函数来创建一个新的内存池,并指定每个对象的大小、对象数量以及其他参数。

(3) mbuf和内存池的关系

  • 一个mbuf包含一个字段pool,用于指示该mbuf来源的内存池。
  • 当分配新的mbuf时,实际上是从指定的内存池中取出一个空闲的内存块。
  • 当释放mbuf时,通过调用rte_pktmbuf_free(m)函数,mbuf会被归还到其原始的内存池中,这样可以被再次使用。

(4) 优化性能

  • 内存池的设计考虑了缓存的优化,确保对象分配和释放操作尽可能地缓存友好,从而提高整体性能。
  • 数据包头在不同的内存通道和组之间交错排列,有助于优化L3缓存的处理。

(5) 共享和多用途

  • 内存池可以在多个核心之间共享,支持并行处理。
  • 除了用于网络数据包的存储,内存池还可以用于其他需要高效内存管理的场景,如事件处理和控制信息存储。
1.4 mbuf对象池构造过程

在DPDK中,消息缓冲区(mbuf)的构造过程由API提供的构造函数完成。以下是详细的构造过程:

(1) 内存池的创建,首先,需要创建一个内存池(mempool),用于存储mbuf对象。通过调用rte_mempool_create()函数来创建内存池。在创建内存池时,可以传递一个回调函数,用于初始化每个mbuf对象。

(2) mbuf的初始化,DPDK提供了一个默认的mbuf初始化函数rte_pktmbuf_init()

这个函数在创建内存池时作为回调函数传递给rte_mempool_create(),用于初始化每个mbuf对象。rte_pktmbuf_init()函数会初始化mbuf结构中的一些字段,这些字段一旦设置就不会被用户修改。具体初始化的字段包括:

  • mbuf类型(mbuf type)
  • 来源的内存池(origin pool)
  • 缓冲区的起始地址(buffer start address)
  • 其他一些需要初始化的字段
void rte_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg, void *_m, unsigned i) {
    struct rte_mbuf *m = _m;

	memset(m, 0, mbuf_size);
	/* start of buffer is after mbuf structure and priv data */
	m->priv_size = priv_size; //mbuf应用数据空间大小,在私有应用数据之后才是报文数据存储空间
	m->buf_addr = (char *)m + sizeof(struct rte_mbuf) + priv_size; 
	rte_mbuf_iova_set(m, rte_mempool_virt2iova(m) + mbuf_size);
	m->buf_len = (uint16_t)buf_len; //mbuf数据空间大小, 包括headroom和tailroom

	/* keep some headroom between start of buffer and data */
	m->data_off = RTE_MIN(RTE_PKTMBUF_HEADROOM, (uint16_t)m->buf_len);

	/* init some constant fields */
	m->pool = mp;
	m->nb_segs = 1;
	m->port = RTE_MBUF_PORT_INVALID;
	rte_mbuf_refcnt_set(m, 1);
	m->next = NULL;
}
2. mbuf对象定义
2.1 mbuf数据结构

相关字段如下:

字段大小描述
cacheline0
buf_addr8 bytes(void *)报文数据的起始地址(虚拟地址)
buf_iova8 bytes(rte_iova_t)报文数据的起始地址(物理地址),总是对齐8字节
rearm_data在RX描述重装时会自动清除接下来8个字节的数据
data_off2 bytes(uint16_t)报文数据的偏移量(相对于buf_addr)
refcnt2 bytes(uint16_t)mbuf引用计数, 用于广播报文零拷贝
nb_segs2 bytes(uint16_t)mbuf的分段sbuf链节点数目,对于一个mbuf不够的报文有效
port2 bytes(uint16_t)报文的输入/输出端口ID(port)
ol_flags8 bytes(uint64_t)网卡硬件卸载特性
rx_descriptor_fields1
packet_type4 bytes(uint32_t)报文数据类型(L2/L3/L4层和隧道信息)
l2_type(4 bits)外层报文的L2类型信息
l3_type(4 bits)外层报文的L3类型信息
l4_type(4 bits)外层报文的L4类型信息
tun_type(4 bits)隧道类型信息
inner_esp_next_proto(8 bit)inner_esp_next_proto(隧道内层信息)
inner_l2_type(4 bit)内层报文的L2类型信息
inner_l3_type(4 bit)内层报文的L3类型信息
inner_l4_type(4 bit)内层报文的L4类型信息
pkt_lenuint32_t(4 byte)整个报文长度(包括所有关联mbuf的数据长度之和)
data_lenuint16_t(2 byte)当前mbuf的报文数据长度(只计算当前mbuf的数据空间)
vlan_tciuint16_t(2 type)(cpu order)VLAN ID,如果RTE_MBUF_F_RX_VLAN存在
hash8 bytes(联合体)报文hash相关信息
rss(4 byte)网卡RSS哈希的结果
fdir(8 byte)网卡FDIR的标识信息 ,包括lo(hash+id) + hi
sched( 8byte)调度队列信息(queue id/traffic class/color)
txadater(8 bytes)dpdk事件设备(eventdev)的关联发送队列(txq)
vlan_tci_outeruint16_t(2 bytes)(cpu order)外层VLAN ID,如果RTE_MBUF_F_RX_QINQ存在
buf_lenuint16_t(2 bytes)当前mbuf的数据空间大小(初始化时给定值)
poolstruct rte_mempool*(8 bytes)当前mbuf所属的内存池
cacheline10 byte
nextstruct rte_mbuf *(8 bytes)长报文的分段mbuf链表,最后一个节点next需要为零
tx_offloaduint64_t (8 bytes)发送网卡硬件卸载信息
l2_lenL2 (MAC) Header Length for non-tunneling pkt。
Outer_L4_len + … + Inner_L2_len for tunneling pkt
l3_lenL3 (IP) Header Length.
l4_lenL4 (TCP/UDP) Header Length.
tso_segszTCP TSO segment size
outer_l3_lenOuter L3 (IP) Hdr Length
outer_l2_lenOuter L2 (MAC) Hdr Length
shinfo12 bytesstruct rte_mbuf_ext_shared_info,mbuf关联的外部数据信息。
priv_sizeuint16_t(2 bytes)mbuf私有数据大小,作为外层应用的mbuf的实际大小来使用。
timesyncuint16_t(2 bytes)Timesync flags for use with IEEE1588
dynfield19 * 4 bytes动态使用字段
2.3 mbuf操作函数定义

相关操作函数和宏定义如下:

操作名称描述
rte_pktmbuf_mtod_offset返回在指定偏移量处的指定类型指针,使用需要注意mbuf数据地址的连续性(是否都在一个mbuf里),即mbuf->buf_addr + mbuf->data_off + offset位置。
rte_pktmbuf_mtod返回偏移量0处指定类型指针,即mbuf->buf_addr + mbuf->data_off位置。
rte_pktmbuf_iova_offset与rte_pktmbuf_mtod_offset类似,但返回的是物理地址(而不是虚拟地址)。
rte_pktmbuf_iova与rte_pktmbuf_mtod类似,但返回的是物理地址(而不是虚拟地址)。
rte_get_rx_ol_flag_name获取Rx offload标识的字符串化表示,一次一个。
rte_get_rx_ol_flag_list获取Rx offload标识的字符串化表示,可以多个标识。
rte_get_tx_ol_flag_name获取Tx offload标识的字符串化表示,一次一个。
rte_get_tx_ol_flag_list获取Rx offload标识的字符串化表示,可以多个标识。
rte_mbuf_prefetch_part1L1缓存预取mbuf第一个cache line的数据
rte_mbuf_prefetch_part2L1缓存预取mbuf第二个cache line的数据
rte_mbuf_iova_get获取mbuf数据的IOVA(虚拟IO地址,IOMMU管理和映射)(mbuf->buf_iova)。
如果RTE_IOVA_IN_MBUF未使能,则等于虚拟地址(mbuf->buf_addr)。
rte_mbuf_iova_set设置IOVA地址,如果RTE_IOVA_IN_MBUF使能,改变mbuf->buf_iova,否则无操作。
rte_mbuf_data_iova获取mbuf报文数据的起始IOVA地址,加上mbuf->data_off。
rte_mbuf_data_iova_default返回默认的mbuf报文数据的起始IOVA地址,固定data offset为RTE_PKTMBUF_HEADROOM(128)
rte_mbuf_from_indirect从一个indirect mbuf的bufffer addr获取其direct(源) mbuf的首地址(指针偏移得到)。
rte_mbuf_buf_addr从mbuf的地址和mempool对象获取mbuf buffer addr
rte_mbuf_data_addr_default从mbuf的地址和mempool对象获取mbuf buffer addr + RTE_PKTMBUF_HEADROOM地址
rte_mbuf_to_baddr获取mbuf buffer addr,从mbuf地址+mempool对象里的mbuf私有数据空间大小算出
rte_mbuf_to_priv返回mbuf私有数据空间的起始地址
rte_pktmbuf_priv_flags返回mbuf私有数据的flags,这是mbuf提供的一种标准私有数据定义。
rte_mbuf_sanity_checkmbuf合规检测,通常用于debug模式,有问题直接panic。
rte_mbuf_checkmbuf合规检测,通常用于debug模式,有问题返回错误原因字符串。
__rte_mbuf_raw_sanity_check原始mbuf合规检测(refcnt=1, next=null, nb_segs=1,通常用于debug模式,有问题直接panic。
rte_mbuf_refcnt_read读取mbuf引用计数,relaxed松散内存序。
rte_mbuf_refcnt_set写入mbuf引用计数,relaxed松散内存序。
__rte_mbuf_refcnt_update更新mbuf引用计数,获取-释放内存序(acquire &release )
rte_mbuf_ext_refcnt_read读取mbuf扩展共享数据的引用计数,relaxed松散内存序。
rte_mbuf_ext_refcnt_set设置mbuf扩展共享数据的引用计数,relaxed松散内存序。
rte_mbuf_ext_refcnt_update更新mbuf扩展共享数据的引用计数,获取-释放内存序(acquire &release )
rte_mbuf_raw_alloc原始方式从mempool申请一个mbuf,buf_addr/buf_iova/buf_len/refcnt=1/nb_segs/next/pool/priv_size等信息应该为重置值。
rte_mbuf_raw_free原始方式释放一个mbuf到mempool,不建议使用,除非优化性能。
rte_pktmbuf_initmempool创建时的初始化函数,用于初始化mbuf全局默认值。
priv_size/buf_addr/buf_iova/buf_len/data_off/pool/nb_segs/port/refcnt/next
其中data_off/nb_segs/port/refcnt/next属于会change的值,需要释放时reset。
rte_pktmbuf_pool_init初始化mempool中私有数据,主要是mbuf的数据空间和私有应用数据空间的大小。
rte_pktmbuf_pool_create创建一个mbuf mempool,提供mbuf数目,私有应用数据和报文数据空间大小等参数。
rte_pktmbuf_pool_create_by_ops与rte_pktmbuf_pool_create类似,但是可以指定mempool ops name。
rte_pktmbuf_pool_create_extbuf与rte_pktmbuf_pool_create类似,但是mbuf的数据存放于外部memory空间。
rte_pktmbuf_data_room_size获取mbuf的数据空间大小(包括RTE_PKTMBUF_HEADROOM)
rte_pktmbuf_priv_size获取mbuf的私有应用数据空间大小,在rte_mbuf和报文数据之间。
rte_pktmbuf_reset_headroom重置mbuf的data_off到默认的headroom起始位置。
rte_pktmbuf_reset重置mbuf的数据,next/pkt_len/tx_offload/vlan_tci/vlan_tci_outer/nb_segs/
port/ol_flags/packet_type/data_off/data_len已初始化。
rte_pktmbuf_alloc从内存池中申请一个mbuf,然后使用rte_pktmbuf_reset进行重置
rte_pktmbuf_alloc_bulk一次从内存池申请多个mbuf,然后使用rte_pktmbuf_reset进行重置
rte_pktmbuf_ext_shinfo_init_helper初始化mbuf的外部共享信息数据结构体,数据需要满足对齐关系。
rte_pktmbuf_attach_extbuf初始化mbuf的外部共享数据,改变buf_addr/buf_iova/buf_len/data_len/data_off=0/ol_flags/shinfo。
修改完成之后,可以调用rte_pktmbuf_reset_headroom/rte_pktmbuf_adj来修复data_len和data_off的值。
rte_pktmbuf_detach_extbufrte_pktmbuf_detach一致。
rte_mbuf_dynfield_copy拷贝rte_mbuf的动态字段dynfield的值。
__rte_pktmbuf_copy_hdr拷贝rte_mbuf的头部数据,port/vlan_tci/vlan_tci_outer/tx_offload/hash/packet_type。
调用rte_mbuf_dynfield_copy拷贝动态空间数据。
rte_pktmbuf_attach将一个mbuf attach到另外一个mbuf上,这种mbuf成为indirect mbuf。
indirect mbuf在attach之前,必须是direct mbuf,其refcnt计数必须为1。
目标mbuf是extbuf,则增加shared info的引用计数,且拷贝ol_flags和shinfo。
目标mbuf是indirect mbuf,增加其源mbuf的引用计数,和普通mbuf一样,拷贝priv_size和ol_flags。
调用**__rte_pktmbuf_copy_hdr**拷贝头部数据。
拷贝data_off/data_len/buf_iova/buf_addr/buf_len/next/pkt_len/nb_segs=1。
__rte_pktmbuf_free_extbuf释放mbuf的extbuf,通过shinfo信息,如果shinfo引用计数为0,则释放extbuf。
__rte_pktmbuf_free_direct减少direct mbuf的引用数目,如果引用计数为0,则直接释放掉direct mbuf。
next/nb_segs=1/refcnt=1, 然后放回mempool
rte_pktmbuf_detach解除一个indirect mbuf的attach状态。
如果mbuf存在extbuf,对于Pinned类型直接Pass。对于其他类型,则调用__rte_pktmbuf_free_extbuf
如果不存在extbuf,直接调用__rte_pktmbuf_free_direct,释放对应的direct mbuf。
重置priv_size,buf_addr,buf_iova,buf_len,data_off,data_len,ol_flags。
__rte_pktmbuf_pinned_extbuf_decrefmbuf释放过程的pinned extbuf处理,重置ol_flags = RTE_MBUF_F_EXTERNAL
如果引用计数为1,则直接结束。如果不为1,则先减去1,最后操作返回值为0的线程再重置为1。
rte_pktmbuf_prefree_seg减少mbuf引用计数,并且判断是否可以free mbuf segment。
mbuf引用计数为1,如果mbuf是indirect mbuf,调用rte_pktmbuf_detach
对于indirect mbuf且存在pinned extbuf,如果extbuf refcnt为1,则需要释放mbuf segment。
mbuf释放操作:next=null,nb_segs=1,返回mbuf(可以回收和释放)。
mbuf引用计数不为1,则减一后为0的线程继续上述释放操作,并且重置mbuf引用计数为1。
rte_pktmbuf_free_seg通过rte_pktmbuf_prefree_seg判读mbuf segment是否可以释放,通过rte_mbuf_raw_free来释放。
rte_pktmbuf_free释放mbuf到mempool池中,支持chain mbuf释放操作。
rte_pktmbuf_free_bulk批量释放mbuf到mempool池中,相当于可以临时缓存mbuf。
rte_pktmbuf_clone基于已有mbuf创建一个clone mbuf,每个mbuf segment都会attach,原mbuf会变成只读mbuf。
rte_pktmbuf_copy基于已有mbuf创建一个全量复制的mbuf,但是private data不会拷贝,两个mbuf将是独立存在的。
可以指定拷贝的报文数据长度,调用**__rte_pktmbuf_copy_hdr**来copy头部。
拷贝会去掉RTE_MBUF_F_INDIRECT和RTE_MBUF_F_EXTERNAL,拷贝后mbuf具有完整的数据。
拷贝mbuf不是逐个mbuf segment拷贝,而是会重新整合数据,尽量填充每个mbuf segment。
rte_pktmbuf_refcnt_update更新mbuf的每个mbuf segment的引用计数。
rte_pktmbuf_headroom获取mbuf的headroom长度,来自data_off。
rte_pktmbuf_tailroom获取mbuf的tailroom长度,来自buf_len - data_off - data_len。
rte_pktmbuf_lastseg获取mbuf的最后一个lastseg。
rte_pktmbuf_pkt_len获取mbuf的报文长度。
rte_pktmbuf_data_len获取mbuf的数据长度。
rte_pktmbuf_prependmbuf报文数据向前扩展指定字节,即尝试减少headroom空间,所以最大上限是headroom大小(data_off=0)。
rte_pktmbuf_append在mbuf后面添加指定字节的数据,尝试减少tailroom,如果空间不足,返回NULL。
rte_pktmbuf_adj移动mbuf的报文数据指针,即data_off,只在第一个mbuf segment移动,不能超过data_len。
rte_pktmbuf_trim裁剪mbuf的尾部数据,裁剪数据长度不能超过最后一个mbuf segment的数据长度(data_len)。
rte_pktmbuf_is_contiguous检查mbuf的数据空间是否连续,即mbuf->nb_segs==1。
__rte_pktmbuf_read在mbuf指定偏移处读取指定长度的数据。
rte_pktmbuf_read如果目标数据是连续的,那么直接返回对应地址的指针,如果非连续,则拷贝到用户buffer中。
rte_pktmbuf_chain将两个mbuf连接起来。
rte_mbuf_tx_offload基于给定的offload参数生成tx_offload值。
rte_validate_tx_offload检查tx_offload的正确性和完整性(ol_flags)。
rte_pktmbuf_linearize将mbuf的数据连续化,要求单个mbuf能放下数据,并且原来的多个mbuf segment被free掉了。
rte_pktmbuf_dump可以dump mbuf的数据。
rte_mbuf_sched_queue_get获取mbuf调度队列的ID。
rte_mbuf_sched_traffic_class_get获取mbuf的traffic class id。
rte_mbuf_sched_color_get获取mbuf的color字段ID。
rte_mbuf_sched_get获取mbuf的queue_id/traffic_class/color的值。
rte_mbuf_sched_queue_set设置mbuf的队列ID。
rte_mbuf_sched_traffic_class_set设置mbuf的class ID。
rte_mbuf_sched_color_set设置mbuf的color ID。
rte_mbuf_sched_set设置mbuf的queue_id, traffic_class and color。

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

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

相关文章

Java面试题--JVM大厂篇之深入解析G1 GC——革新Java垃圾回收机制

目录 引言: 正文&#xff1a; 一、G1 GC的区域划分及其作用 1. 伊甸园区&#xff08;Eden Region&#xff09; 2. 幸存者区&#xff08;Survivor Region&#xff09; 3. 老年代区&#xff08;Old Generation Region&#xff09; 二、区域划分的优势: 三、图片解析: 结…

记录自己Ubuntu加Nvidia驱动从入门到入土的一天

前言 记录一下自己这波澜壮阔的一天&#xff0c;遇到了很多问题&#xff0c;解决了很多问题&#xff0c;但是还有很多问题&#xff0c;终于在晚上的零点彻底放弃&#xff0c;重启windows。 安装乌班图 1.安装虚拟机 我开始什么操作系统的基础都没有&#xff0c;网上随便搜了…

代码随想录算法训练营第四十九天| 300.最长递增子序列 , 674. 最长连续递增序列 , 718. 最长重复子数组

300. 最长递增子序列 - 力扣&#xff08;LeetCode&#xff09; class Solution {public int lengthOfLIS(int[] nums) {int[] dp new int[nums.length];dp[0] 1;for(int i1;i<nums.length;i){for(int j0;j<i;j){if(nums[i] > nums[j]){dp[i] Math.max(dp[j],dp[i])…

(十) Docker compose 本地部署 apollo

文章目录 1、apollo2、数据库准备3、启动后会用到的几个地址4、docker-compose运行 apollo方式一&#xff1a;使用容器 hostName 作为网络媒介方式二&#xff1a;使用端口映射固定 ip 作为网络媒介 6、客户端 1、apollo https://www.apolloconfig.com/#/zh/deployment/quick-s…

微软Edge浏览器全解析:从速度到安全性的全面体验

微软Edge浏览器&#xff0c;自2015年首次亮相以来&#xff0c;已经成为了浏览器市场上不可忽视的一股力量。它不仅集成了Windows 10的许多原生功能&#xff0c;还在速度和安全性上进行了大量的优化。本文将全面解析微软Edge浏览器的各项特性&#xff0c;带您领略这款浏览器的魅…

Linux笔记之三

Linux笔记之三 一、用户组管理二、磁盘管理三、进程管理总结 一、用户组管理 每个用户都有一个用户组&#xff0c;系统可以对一个用户组中的所有用户进行集中管理&#xff08;开发、测试、运维、root&#xff09;。不同Linux系统对用户组的管理涉及用户组的添加、删除和修改。…

基于Java+SpringMvc+Vue技术的图书管理系统的设计与实现(60页论文参考)

博主介绍&#xff1a;硕士研究生&#xff0c;专注于Java技术领域开发与管理&#xff0c;以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年&#xff0c;拥有近12年的管理工作经验&#xff0c;拥有较丰富的技术架构思想、较扎实的技术功底和资深的项目管理经…

防火墙概述

1、防火墙 防火墙顾名思义就是防止火灾发生时&#xff0c;火势烧到其它区域&#xff0c;使用由防火材料砌的墙。在网络安全中&#xff0c;防火墙的作用就是保护本地网络不受到外部网络或恶意程序的伤害。 防火墙的核心任务是控制和防护&#xff0c;即通过安全策略识别流量并做…

Kafka抛弃Zookeeper后如何启动?

Kafaka如何下载 官网地址 目前Kafka最新的版本就是3.7.1 我们可以看到下面这两个版本信息&#xff1f;什么意思呢&#xff1f; Scala 2.12 - kafka_2.12-3.7.1.tgz (asc, sha512)Scala 2.13 - kafka_2.13-3.7.1.tgz (asc, sha512) 我们应该知道&#xff0c;一个完整的Kafka实…

【Excel】把一列姓名快速填充到多列表格

目录标题 1. 输入A1 → 向右填充 → 输入A5 → 向右填充2. 选中2行单元格 → 向下填充3. CtrlH → 替换 → 全部替换 1. 输入A1 → 向右填充 → 输入A5 → 向右填充 2. 选中2行单元格 → 向下填充 3. CtrlH → 替换 → 全部替换

用Goaccess对Web及雷池WAF日志实现可视化分析

君衍. 一、项目环境介绍二、Goaccess1、Goaccess介绍2、存储方式3、配置选项4、自定义日志/日期格式5、特殊格式说明符 三、雷池访问日志1、配置文件改变2、docker配置3、示例测试 四、Goaccess安装1、安装依赖2、编译安装 五、Goaccess对Nginx日志分析1、常用命令参数2、终端模…

【server】springboot 整合 redis

1、redis 使用模式 1.1 单机模式 1.1.1 编译安装方式 1.1.1.1 下载 Redis的安装非常简单&#xff0c;到Redis的官网&#xff08;Downloads - Redis&#xff09;&#xff0c;下载对应的版本&#xff0c;简单几个命令安装即可。 1.1.1.2 编译安装 tar xzf redis-stable.tar.…

【链表】【双指针】1、环形链表+2、环形链表 II+3、相交链表

2道简单1道中等&#xff0c;链表的双指针相关问题就告一段落&#xff0c;下一步刷新的题目。 1、环形链表&#xff08;难度&#xff1a;简单&#xff09; 该题对应力扣网址 AC代码 常见思路&#xff0c;slow指针每次走一步&#xff0c;fast指针每次走两步&#xff0c;如果fa…

大语言模型基础

大语言基础 GPT : Improving Language Understanding by Generative Pre-Training 提出背景 从原始文本中有效学习的能力对于减轻自然语言处理中对监督学习的依赖至关重要。很多深度学习方法需要大量人工标注的数据&#xff0c;限制了它们在很多领域的应用&#xff0c;收集更…

Learn To Rank

在信息检索中&#xff0c;给定一个query&#xff0c;搜索引擎召回一系列相关的Documents&#xff0c;然后对这些Documents进行排序&#xff0c;最后将Top N的Documents输出。 排序问题最关注的是各Documents之间的相对顺序关系&#xff0c;而不是各个Documents的预测分最准确。…

如何优化 PostgreSQL 中对于自关联表的查询?

文章目录 一、理解自关联表查询二、分析性能问题的可能原因&#xff08;一&#xff09;缺少合适的索引&#xff08;二&#xff09;大量数据的笛卡尔积&#xff08;三&#xff09;复杂的查询逻辑 三、优化策略及解决方案&#xff08;一&#xff09;创建合适的索引&#xff08;二…

Rejetto HFS 服务器存在严重漏洞受到攻击

AhnLab 报告称 &#xff0c;黑客正在针对旧版本的 Rejetto HTTP 文件服务器 (HFS) 注入恶意软件和加密货币挖矿程序。 然而&#xff0c;由于存在错误&#xff0c; Rejetto 警告用户不要使用 2.3 至 2.4 版本。 2.3m 版本在个人、小型团队、教育机构和测试网络文件共享的开发…

7.pwn 工具安装和使用

关闭保护的方法 pie: -no-pie Canary:-fno-stack-protector aslr:查看:cat /proc/sys/kernel/randomize_va_space 2表示打开 关闭:echo 0>/proc/sys/kernel/randomize_va_space NX:-z execstack gdb使用以及插件安装 是GNU软件系统中的标准调试工具&#xff0c;此外GD…

2024/7/7周报

文章目录 摘要Abstract文献阅读题目问题本文贡献问题描述图神经网络Framework实验数据集实验结果 深度学习MAGNN模型相关代码GNN为什么要用GNN&#xff1f;GNN面临挑战 总结 摘要 本周阅读了一篇用于多变量时间序列预测的多尺度自适应图神经网络的文章&#xff0c;多变量时间序…

Windows密码凭证获取

Windows HASH HASH简介 hash &#xff0c;一般翻译做散列&#xff0c;或音译为哈希&#xff0c;所谓哈希&#xff0c;就是使用一种加密函数进行计算后的结果。这个 加密函数对一个任意长度的字符串数据进行一次数学加密函数运算&#xff0c;然后返回一个固定长度的字符串。…