Linux内存管理之slab 2:slab API

https://blog.csdn.net/lqy971966/article/details/119801912

1. 为什么有了Buddy(伙伴系统)还需要slab?

1.1 什么是伙伴系统?

Linux内核中使用伙伴系统(buddy system)算法以页为单位管理内存,进行内存分配。

1.1.1 伙伴系统思想

它把所有的空闲页放到11个链表中,每个链表分别管理大小为1,2,4,8,16,32,64,128,256,512,1024个页的内存块。当系统需要分配内存时,就可以从buddy系统中获取。

1.2 伙伴系统例子说明

例如,要申请一块包含4个页的连续内存,就直接从buddy系统中管理4个页连续内存的链表中获取。同样的,如果系统需要申请3个页的连续内存,则只能在4个页的链表中获取,剩下的一个页被放到buddy系统中管理1个页的链表中。

1.3 伙伴系统能解决的问题

Buddy 系统解决了物理内存分配的外部碎片问题。

Linux内存管理 - buddy系统

https://www.cnblogs.com/longchang/p/10749392.html

2 为什么需要引入slab算法?

2.1 伙伴系统的缺点

Buddy提供了以page为单位的内存分配接口,这对内核来说颗粒度还太大了,所以需要一种新的机制,将page拆分为更小的单位来管理。

2.2 伙伴系统的缺点例子说明

Linux内存以页为单位进行内存管理,buddy算法以2的n次方个页面来进行内存分配管理,最小为20,也就是一页,最大为211,就是4MB大小的连续内存空间。但是页的粒度还是太大,Linux下是4KB大小,也就是4096个字节,而kernel本身有很多数据结构时时刻刻都需要分配或者释放,这些数据的大小又往往小于4KB大小,一般只有几个几十个字节这样的大小。

比方最常用到的task_struct(进程描述符)结构体和mm_struct(内存描述符)结构体,其中,izeof task_struct = 9152,sizeof mm_struct = 2064。

task_struct稍微大一点将近2个页面,mm_struct就只有差不多半个页面了。这样一来如果所有的这些数据结构都按照页来分配存储和管理,那么我相信kernel过不了多久自己就玩完了,内存碎片肯定一堆一堆。

所以,引入slab分配器是为了弥补内存管理粒度太大的不足。

3. slab 能解决什么问题?

slab分配需要解决的是内存的内部碎片问题。

所谓内部碎片就是指被内核分配出去但是不能被利用的内存。

而外部碎片是指由于频繁地申请和释放页框而导致的某些小的连续页框,比方只有一个页框,无法分配给需要大的连续页框的进程而导致的内存碎片。

3.3 slab 分配例子

比如我需要一个100字节的连续物理内存,那么内核slab分配器会给我提供一个相应大小的连续物理内存单元,为128字节大小(不会是整好100字节,而是这个档的一个对齐值,如100字节对应128字节,30字节对应32字节,60字节对应64字节)

4. slab系统核心思想是什么?

4.0. 须知:

kmem_cache: 内存池
slab: 内存池从系统申请内存的基本单位
object: 内存池提供的内存的单位
123

4.1 slab核心思想:对象管理内存(简单说:就是你经常用什么我先给你创造一堆出来,你要用直接拿,不用放回来)

使用对象的概念来管理内存。

slab分配器的基本思想是,先利用页面分配器分配出单个或者一组连续的物理页面,然后在此基础上将整块页面分割成多个相等的小内存单元,以满足小内存空间分配的需要。当然,为了有效的管理这些小的内存单元并保证极高的内存使用速度和效率。

这段话摘自:《深入linux设备驱动程序内核机制》

https://blog.csdn.net/yuzhihui_no1/article/details/47305361

4.2 slab的对象/内存池思想

在内核中,经常会使用一些链表,链表中会申请许多相同结构的结构体,比如文件对象,进程对象等等,如果申请比较频繁,那么为它们建立一个内存池,内存池中都是相同结构的结构体,当想申请这种结构体时,直接从这种内存池中取一个结构体出来,是有用且速度极快的。一个物理页就可以作用这种内存池的载体,进而进行充分利用,减少了内部碎片的产生。

所以,Slab 相当于内存池思想,且是为了解决内碎片而产生的,slab的核心思想是以对象的观点管理内存。

4.3 slab中对象是什么?

所谓的对象就是存放一组数据结构的内存区,为便于理解可把对象看作内核中的数据结构(例如:task_struct,file_struct 等)。

相同类型的对象归为一类,每当要申请这样一个对象时,slab分配器就从一个slab列表中分配一个这样大小的单元出去,而当要释放时,将其重新保存在该列表中,而不是直接返回给伙伴系统,从而避免内部碎片。

4.4 cache是内存中的区域,而不是指硬件高速缓存

这种场景是非常多的,为了应对这种场景,slab为这样的对象创建一个cache,即缓存。每个cache所占的内存区又被划分多个slab,每个 slab是由一个或多个连续的页框组成。每个页框中包含若干个对象,既有已经分配的对象,也包含空闲的对象。

尽管英文中使用了Cache这个词,但实际上指的是内存中的区域,而不是指硬件高速缓存

4.5 lab分配器的一个基本原则

slab分配器对不同长度内存是分档的,这是slab分配器的一个基本原则,按申请的内存的大小分配相应长度的内存。

这可以先参考kmalloc的实现,kmalloc申请的物理内存长度为参数size,它需要先根据这个长度找到相应的长度的缓存

slab分配器并非一开始就能智能的根据内存分档值分配相应长度的内存。每种cache对应一种长度的slab分配。

5 slab分配的最小和最大内存单元是多少?

23、………211个字节。

另外还有两个特殊的组,分别是96B和192B,共11组

所以,slab分配内存大小是:

8B,16B,32B,64B,96B,128B,192B,256B,512B,1024B,2048B等大小。共11组

5.1 cat /proc/slabinfo 查看系统中的slab对象

[root@localhost 10]# cat /proc/slabinfo
slabinfo - version: 2.1
# name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
rpc_inode_cache 51 51 640 51 8 : tunables 0 0 0 : slabdata 1 1 0
xfs_dqtrx 0 0 528 62 8 : tunables 0 0 0 : slabdata 0 0 0
xfs_dquot 0 0 488 67 8 : tunables 0 0 0 : slabdata 0 0 0
xfs_ili 2160 2160 168 48 2 : tunables 0 0 0 : slabdata 45 45 0
xfs_inode 21352 21352 960 34 8 : tunables 0 0 0 : slabdata 628 628 0
xfs_efd_item 156 156 416 39 4 : tunables 0 0 0 : slabdata 4 4 0
xfs_btree_cur 39 39 208 39 2 : tunables 0 0 0 : slabdata 1 1 0
xfs_log_ticket 44 44 184 44 2 : tunables 0 0 0 : slabdata 1 1 0
bio-2 51 51 320 51 4 : tunables 0 0 0 : slabdata 1 1 0
kcopyd_job 0 0 3312 9 8 : tunables 0 0 0 : slabdata 0 0 0
dm_uevent 0 0 2608 12 8 : tunables 0 0 0 : slabdata 0 0 0
dm_rq_target_io 0 0 136 60 2 : tunables 0 0 0 : slabdata 0 0 0
ip6_dst_cache 72 72 448 36 4 : tunables 0 0 0 : slabdata 2 2 0
RAWv6 286 286 1216 26 8 : tunables 0 0 0 : slabdata 11 11 0
UDPLITEv6 0 0 1216 26 8 : tunables 0 0 0 : slabdata 0 0 0
UDPv6 26 26 1216 26 8 : tunables 0 0 0 : slabdata 1 1 0
tw_sock_TCPv6 0 0 256 64 4 : tunables 0 0 0 : slabdata 0 0 0
TCPv6 15 15 2176 15 8 : tunables 0 0 0 : slabdata 1 1 0
cfq_queue 70 70 232 70 4 : tunables 0 0 0 : slabdata 1 1 0
bsg_cmd 0 0 312 52 4 : tunables 0 0 0 : slabdata 0 0 0
mqueue_inode_cache 36 36 896 36 8 : tunables 0 0 0 : slabdata 1 1 0
hugetlbfs_inode_cache 53 53 608 53 8 : tunables 0 0 0 : slabdata 1 1 0
configfs_dir_cache 0 0 88 46 1 : tunables 0 0 0 : slabdata 0 0 0
dquot 0 0 256 64 4 : tunables 0 0 0 : slabdata 0 0 0
userfaultfd_ctx_cache 0 0 192 42 2 : tunables 0 0 0 : slabdata 0 0 0
fanotify_event_info 73 73 56 73 1 : tunables 0 0 0 : slabdata 1 1 0
pid_namespace 0 0 2200 14 8 : tunables 0 0 0 : slabdata 0 0 0
posix_timers_cache 66 66 248 66 4 : tunables 0 0 0 : slabdata 1 1 0
UDP-Lite 0 0 1088 30 8 : tunables 0 0 0 : slabdata 0 0 0
flow_cache 0 0 144 56 2 : tunables 0 0 0 : slabdata 0 0 0
xfrm_dst_cache 0 0 576 56 8 : tunables 0 0 0 : slabdata 0 0 0
UDP 30 30 1088 30 8 : tunables 0 0 0 : slabdata 1 1 0
tw_sock_TCP 0 0 256 64 4 : tunables 0 0 0 : slabdata 0 0 0
TCP 16 16 1984 16 8 : tunables 0 0 0 : slabdata 1 1 0
dax_cache 42 42 768 42 8 : tunables 0 0 0 : slabdata 1 1 0
blkdev_queue 26 26 2424 13 8 : tunables 0 0 0 : slabdata 2 2 0
blkdev_ioc 78 78 104 39 1 : tunables 0 0 0 : slabdata 2 2 0
user_namespace 68 68 480 68 8 : tunables 0 0 0 : slabdata 1 1 0
dmaengine-unmap-128 30 30 1088 30 8 : tunables 0 0 0 : slabdata 1 1 0
sock_inode_cache 1020 1020 640 51 8 : tunables 0 0 0 : slabdata 20 20 0
fsnotify_mark_connector 129370 129370 24 170 1 : tunables 0 0 0 : slabdata 761 761 0
net_namespace 6 6 5248 6 8 : tunables 0 0 0 : slabdata 1 1 0
shmem_inode_cache 1200 1200 680 48 8 : tunables 0 0 0 : slabdata 25 25 0
Acpi-ParseExt 6440 6440 72 56 1 : tunables 0 0 0 : slabdata 115 115 0
Acpi-State 102 102 80 51 1 : tunables 0 0 0 : slabdata 2 2 0
task_delay_info 288 288 112 36 1 : tunables 0 0 0 : slabdata 8 8 0
taskstats 49 49 328 49 4 : tunables 0 0 0 : slabdata 1 1 0
proc_inode_cache 1621 1813 656 49 8 : tunables 0 0 0 : slabdata 37 37 0
sigqueue 51 51 160 51 2 : tunables 0 0 0 : slabdata 1 1 0
bdev_cache 39 39 832 39 8 : tunables 0 0 0 : slabdata 1 1 0
kernfs_node_cache 35360 35360 120 68 2 : tunables 0 0 0 : slabdata 520 520 0
mnt_cache 2478 2478 384 42 4 : tunables 0 0 0 : slabdata 59 59 0
inode_cache 16720 16720 592 55 8 : tunables 0 0 0 : slabdata 304 304 0
dentry 49350 49350 192 42 2 : tunables 0 0 0 : slabdata 1175 1175 0
iint_cache 0 0 128 64 2 : tunables 0 0 0 : slabdata 0 0 0
selinux_inode_security 45798 45798 40 102 1 : tunables 0 0 0 : slabdata 449 449 0
buffer_head 2145 2145 104 39 1 : tunables 0 0 0 : slabdata 55 55 0
vm_area_struct 4699 4699 216 37 2 : tunables 0 0 0 : slabdata 127 127 0
mm_struct 60 60 1600 20 8 : tunables 0 0 0 : slabdata 3 3 0
files_cache 204 204 640 51 8 : tunables 0 0 0 : slabdata 4 4 0
signal_cache 252 252 1152 28 8 : tunables 0 0 0 : slabdata 9 9 0
sighand_cache 255 255 2112 15 8 : tunables 0 0 0 : slabdata 17 17 0
task_xstate 273 273 832 39 8 : tunables 0 0 0 : slabdata 7 7 0
task_struct 255 264 4048 8 8 : tunables 0 0 0 : slabdata 33 33 0
anon_vma 1887 1887 80 51 1 : tunables 0 0 0 : slabdata 37 37 0
shared_policy_node 2635 2635 48 85 1 : tunables 0 0 0 : slabdata 31 31 0
numa_policy 186 186 264 62 4 : tunables 0 0 0 : slabdata 3 3 0
radix_tree_node 2856 2856 584 56 8 : tunables 0 0 0 : slabdata 51 51 0
idr_layer_cache 180 180 2112 15 8 : tunables 0 0 0 : slabdata 12 12 0
dma-kmalloc-8192 0 0 8192 4 8 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-4096 0 0 4096 8 8 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-2048 0 0 2048 16 8 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-1024 0 0 1024 32 8 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-512 64 64 512 64 8 : tunables 0 0 0 : slabdata 1 1 0
dma-kmalloc-256 0 0 256 64 4 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-128 0 0 128 64 2 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-64 0 0 64 64 1 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-32 0 0 32 128 1 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-16 0 0 16 256 1 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-8 0 0 8 512 1 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-192 0 0 192 42 2 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-96 0 0 96 42 1 : tunables 0 0 0 : slabdata 0 0 0
kmalloc-8192 40 40 8192 4 8 : tunables 0 0 0 : slabdata 10 10 0
kmalloc-4096 254 264 4096 8 8 : tunables 0 0 0 : slabdata 33 33 0
kmalloc-2048 955 1072 2048 16 8 : tunables 0 0 0 : slabdata 67 67 0
kmalloc-1024 2894 2976 1024 32 8 : tunables 0 0 0 : slabdata 93 93 0
kmalloc-512 4825 4864 512 64 8 : tunables 0 0 0 : slabdata 76 76 0
kmalloc-256 7406 7552 256 64 4 : tunables 0 0 0 : slabdata 118 118 0
kmalloc-192 7560 7560 192 42 2 : tunables 0 0 0 : slabdata 180 180 0
kmalloc-128 3136 3136 128 64 2 : tunables 0 0 0 : slabdata 49 49 0
kmalloc-96 5334 5334 96 42 1 : tunables 0 0 0 : slabdata 127 127 0
kmalloc-64 84850 85184 64 64 1 : tunables 0 0 0 : slabdata 1331 1331 0
kmalloc-32 125696 125696 32 128 1 : tunables 0 0 0 : slabdata 982 982 0
kmalloc-16 63232 63232 16 256 1 : tunables 0 0 0 : slabdata 247 247 0
kmalloc-8 86528 86528 8 512 1 : tunables 0 0 0 : slabdata 169 169 0
kmem_cache_node 128 128 64 64 1 : tunables 0 0 0 : slabdata 2 2 0
kmem_cache 128 128 256 64 4 : tunables 0 0 0 : slabdata 2 2 0
[root@localhost 10]#
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101

6. slab与buddy系统的关系

6.1 互补的

slab系统与buddy系统所要解决的问题是互补的,一个解决外部碎片一个解决内部碎片,但事实上,slab在新建cache时同样需要用到buddy来为之分配页面,而在释放cache时也需要buddy来回收这此页面。也就是说,slab事实上是依赖buddy系统的。

6.2 实际还是伙伴系统分配物理页

从slab的分配可以知道,其实所有的内存最终还是要伙伴系统来分配,这里就可以知道,这些内存都是连续的物理页。

6.3 slab作为内核缓存对象

在某些情况下内核模块可能需要频繁的分配和释放相同的内存对象,这时候slab可以作为内核对象的缓存,当slab对象被释放时,slab分配器并不会把对象占用的物理空间还给伙伴系统。这样的好处是当内核模块需要再次分配内存对象时,不需要那么麻烦的向伙伴系统申请,而是可以直接在slab链表中分配一个合适的对象

7. slab 配器结构

7.1 slab 结构图

图:

解释:

每个kmem_cache都是链接在一起形成一个全局的双向链表,由cache指向该链表,系统可以从Cache_chain开始扫描每个kmem_cache,来找到一个大小最合适的kmem_cache,然后从该kmem_cache中分配一个对象

7.2 slab 结构解释

7.2.1 cache_chain

最高层是 cache_chain,这是一个 slab 缓存的链接列表。可以用来查找最适合所需要的分配大小的缓存(遍历列表)

cache_chain 的每个元素都是一个 kmem_cache 结构的引用(称为一个 cache)。它定义了一个要管理的给定大小的对象池。

7.2.2 kmem_cache

kmem_cache: 内存池
slab: 内存池从系统申请内存的基本单位
object: 内存池提供的内存的单位
123
7.2.2.1 kmem_cache 或 cache:
有的地方也会叫这个kmem_cache为cache,原因是kmem_cache中的object有大有小(其实也是kmem_cache有大有小),
当内存申请时,会有命中该kmem_cache的说法,和CPU中的cache命中是类似的意思,所以也会叫kmem_cache为cache
12
7.2.2.2 三条链表:slabs_full slabs_partial slabs_empty

每个缓存(kmem_cache)都包含了一个 slabs 列表,这是一段连续的内存块(通常都是页面)

其中每个kmem_cache有三条链表:

slabs_full 表示该链表中每个slab的object对象都已经分配完了
slabs_partial 表示该链表中的slab的object对象部分分配完了
slabs_empty 表示该链表中的object对象全部没有分配出去(空 slab,未分配)
123

对象的分配和释放都是在slab中进行的,所以slab可以在三条链表中移动,如果slab中的object都分配完了,则会移到full 链表中;如果分配了一部分object,则会移到partial链表中;如果所有object都释放了,则会移动到empty链表中;其中当系统内存紧张的时候,slabs_empty链表中的slab可能会被返回给系统。

7.2.2.3 cache_cache 结构体等说明

所有的kmem_cache结构都是从cache_cache分配的

static kmem_cache_t cache_cache = {
slabs_full: LIST_HEAD_INIT(cache_cache.slabs_full),
slabs_partial: LIST_HEAD_INIT(cache_cache.slabs_partial),
slabs_free: LIST_HEAD_INIT(cache_cache.slabs_free),
objsize: sizeof(kmem_cache_t),
flags: SLAB_NO_REAP,
spinlock: SPIN_LOCK_UNLOCKED,
colour_off: L1_CACHE_BYTES,
name: "kmem_cache",
}; struct cache_size{
size_t cs_size;
struct kmem_cache *cs_cachep;
} struct cache_size malloc_sizes[] = {
{.cs_size = 32},
{.cs_size = 64},
{.cs_size = 128},
{.cs_size = 256},
................
{.cs_size = ~0UL},
};
12345678910111213141516171819202122232425

在系统初始化时,内核会调用kmem_cache_init函数对malloc_size数组进行遍历,对数组中的每个元素都调用kmem_cache_create()函数在cache_cache中分配一个struct kmem_cache 实例,并且把kmem_cache所在的地址赋值给cache_size中的cs_cachep指针

7.2.3 slab

slab 列表中的每个 slab 都是一个连续的内存块(一个或多个连续页),它们被划分成一个个对象(如 mm_struct)。

这些对象是从特定缓存中进行分配和释放的基本元素。

8. slab 和 /proc

proc 文件系统提供了一种简单的方法来监视系统中所有活动的 slab 缓存。

这个文件称为 /proc/slabinfo,

它除了提供一些可以从用户空间访问的可调整参数之外,还提供了有关所有 slab 缓存的详细信息。

如:

[root@localhost home]# cat  /proc/slabinfo
slabinfo - version: 2.1
# name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
nf_conntrack_ffffffffb58fc900 51 51 320 51 4 : tunables 0 0 0 : slabdata 1 1 0
rpc_inode_cache 51 51 640 51 8 : tunables 0 0 0 : slabdata 1 1 0
xfs_dqtrx 0 0 528 62 8 : tunables 0 0 0 : slabdata 0 0 0
xfs_dquot 0 0 488 67 8 : tunables 0 0 0 : slabdata 0 0 0
xfs_ili 2016 2016 168 48 2 : tunables 0 0 0 : slabdata 42 42 0
xfs_inode 21182 21182 960 34 8 : tunables 0 0 0 : slabdata 623 623 0
xfs_efd_item 39 39 416 39 4 : tunables 0 0 0 : slabdata 1 1 0
xfs_btree_cur 39 39 208 39 2 : tunables 0 0 0 : slabdata 1 1 0
……
123456789101112

9. slab API

Linux内存管理之slab 2:slab API

https://blog.csdn.net/lqy971966/article/details/119801912

参考:

https://blog.csdn.net/yuzhihui_no1/article/details/47305361

参考:

https://blog.csdn.net/qq_22238021/article/details/80214759

https://zhuanlan.zhihu.com/p/61457076

https://blog.csdn.net/rockrockwu/article/details/79976833

https://www.cnblogs.com/wangzahngjun/p/4977425.html

原文链接:https://blog.csdn.net/lqy971966/article/details/112980005

【转载】内存基本概念-slab算法的更多相关文章

  1. 伙伴算法与slab算法

    伙伴算法: 1.将空闲页面分为m个组,第1组存储2^0个单位的内存块,,第2组存储2^1个单位的内存块,第3组存储2^2个单位的内存块,第4组存储2^3个单位的内存块,以此类推.直到m组. 2.每个组 ...

  2. Linux内存管理 (5)slab分配器

    专题:Linux内存管理专题 关键词:slab/slub/slob.slab描述符.kmalloc.本地/共享对象缓冲池.slabs_partial/slabs_full/slabs_free.ava ...

  3. JVM虚拟机(四):JVM 垃圾回收机制概念及其算法

    垃圾回收概念和其算法 谈到垃圾回收(Garbage Collection)GC,需要先澄清什么是垃圾,类比日常生活中的垃圾,我们会把他们丢入垃圾箱,然后倒掉.GC中的垃圾,特指存于内存中.不会再被使用 ...

  4. JVM内存管理之GC算法精解(复制算法与标记/整理算法)

    本次LZ和各位分享GC最后两种算法,复制算法以及标记/整理算法.上一章在讲解标记/清除算法时已经提到过,这两种算法都是在此基础上演化而来的,究竟这两种算法优化了之前标记/清除算法的哪些问题呢? 复制算 ...

  5. Java内存管理及GC算法

    概述 内存划分 虚拟机规范中将内存分为六大部分,分别为PC寄存器.JAVA虚拟机栈.JAVA堆.方法区.运行时常量及本地方法栈. 1.PC寄存器:线程独占: 2.JAVA虚拟机栈:线程独有:JAVA虚 ...

  6. 一些数论概念与算法——从SGU261谈起

    话说好久没来博客上面写过东西了,之前集训过于辛苦了,但有很大的收获,我觉得有必要把它们拿出来总结分享.之前一直是个数论渣(小学初中没好好念过竞赛的缘故吧),经过一道题目对一些基础算法有了比较深刻的理解 ...

  7. memcached学习——memcached的内存分配机制Slab Allocation、内存使用机制LRU、常用监控记录(四)

    内存分配机制Slab Allocation 本文参考博客:https://my.oschina.net/bieber/blog/505458 Memcached的内存分配是以slabs为单位的,会根据 ...

  8. 内存管理和GC算法以及回收策略

    JVM内存组成结构 JVM栈由堆.栈.本地方法栈.方法区等部分组成,结构图如下所示: JVM内存回收 Sun的JVMGenerationalCollecting(垃圾回收)原理是这样的:把对象分为年青 ...

  9. linux中高端内存和低端内存的概念【转】

    转自:http://blog.csdn.net/hdujinhuihui/article/details/8686817 高端内存是Linux中一个重要的概念,初涉Linux时曾经对这个概念非常迷惑. ...

  10. Linux内存管理6---伙伴算法与slab

    1.前言 本文所述关于内存管理的系列文章主要是对陈莉君老师所讲述的内存管理知识讲座的整理. 本讲座主要分三个主题展开对内存管理进行讲解:内存管理的硬件基础.虚拟地址空间的管理.物理地址空间的管理. 本 ...

随机推荐

  1. [洛谷P8867] [NOIP2022] 建造军营

    [NOIP2022] 建造军营 题目描述 A 国与 B 国正在激烈交战中,A 国打算在自己的国土上建造一些军营. A 国的国土由 \(n\) 座城市组成,\(m\) 条双向道路连接这些城市,使得任意两 ...

  2. 在 JMeter 中使用 JSON 提取器提取特定条件下的值

    当你需要在 JMeter 中对接收到的 JSON 响应进行处理时,JSON 提取器是一个非常有用的工具.在本文中,我们将讨论如何使用 JSON 提取器来提取特定条件下的值,以满足你的需求. 问题描述 ...

  3. Helm Chart 部署 Redis 的完美指南

    目录 一.Helm介绍 二.安装Helm 三.配置Helm的repository 四.部署chart(以部署redis为例) 1. 搜索chart 2. 拉取chart 3. 修改values.yam ...

  4. Oracle数据库卸载器 - 开源研究系列文章

    今天无事,把网上搜到的Oracle数据库卸载器的软件更新到C#的Winform界面的操作上. 1. 程序目录: 与笔者的其它软件类似,目录如下: 2. 使用的类: 这里主要使用了一个处理函数: 3. ...

  5. Git提交修正

    应用场景 日常开发中我们可能会遇到这样的问题 1.提交了代码有错误 2.提交的信息写错了 3.漏了一些文件没有提交 ...... 再或者我们写一个功能时,中间有很多小的提交,这中间就会产生特别多的co ...

  6. 基于Docker Desktop搭建Kafka集群并使用Java编程开发

    一.引言 前段时间因课业要求使用Docker Desktop 部署Kafka集群并编写生产者消费者程序,折磨了我好几天,在查找大量资料后终于是把整个集群搭建完成了.现在我想要分享其中搭建的历程,希望能 ...

  7. 从滑动窗口到YOLO、Transformer:目标检测的技术革新

    本文全面回顾了目标检测技术的演进历程,从早期的滑动窗口和特征提取方法到深度学习的兴起,再到YOLO系列和Transformer的创新应用.通过对各阶段技术的深入分析,展现了计算机视觉领域的发展趋势和未 ...

  8. Oracle密码文件、警告日志文件、跟踪文件

    密码文件 oracle用于验证sysdba权限的二进制文件. 警告日志文件 警告日志文件是用来记录oracle数据库系统在运行期间的各种信息: oracle实例打开和关闭.建立表空间.增加数据文件等记 ...

  9. IntelliJ IDEA官方宣布中文汉化包正式发布-intellijidea-guan-fang-xuan-bu-zhong-wen-han-hua-bao-zheng-shi-fa-bu

    title: IntelliJ IDEA官方宣布中文汉化包正式发布 date: 2021-07-27 16:42:21.823 updated: 2021-12-26 17:43:12.204 url ...

  10. MySQL运维实战(1.1)安装部署:使用RPM进行安装部署

    作者:俊达 我们在生产环境部署mysql时,一般很少使用RedHat Package Manager(RedHat软件包管理工具).用rpm或或者其他包管理器安装mysql有其好处,例如安装简单,并且 ...