常见泽1 发表于 2025-1-7 18:20

《Linux内核深度解析》第三章 内存学习笔记2

<p><span style="font-size:16px;">Linux内存管理是指操作系统对于计算机系统中的内存资源进行有效利用和管理的过程。它包括了内存分配、内存映射等一些方面</span></p>

<p ><span style="font-size:22px;"><strong>一 引导内存分配器</strong></span></p>

<p ><span style="font-size:16px;">在内核初始化的过程中需要分配内存,内核提供了临时的引导内存分配器,在页分配器和块分配器初始化完毕后,把空闲的物理页交给页分配器管理,丢弃引导内存分配器</span></p>

<p ><span style="font-size:16px;">早期使用的引导分配器是bootmem,目前正在使用memblock取代bootmem</span></p>

<p >&nbsp;</p>

<p ><span style="font-size:16px;">查看bootmem_data数据结构</span></p>

<p ><span style="font-size:16px;">typedef struct bootmem_data {&nbsp;</span></p>

<p ><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; unsigned long node_min_pfn;&nbsp;</span></p>

<p ><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; unsigned long node_low_pfn;&nbsp;</span></p>

<p ><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; void *node_bootmem_map;&nbsp;</span></p>

<p ><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; unsigned long last_end_off;&nbsp;</span></p>

<p ><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; unsigned long hint_idx;&nbsp;</span></p>

<p ><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; struct list_head list;&nbsp;</span></p>

<p ><span style="font-size:16px;">} bootmem_data_t;</span></p>

<p >&nbsp;</p>

<p ><span style="font-size:16px;">Memblock数据结构</span></p>

<p ><span style="font-size:16px;">truct memblock_type {&nbsp;</span></p>

<p ><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; unsigned long cnt;&nbsp;&nbsp;&nbsp; /* number of regions */&nbsp;</span></p>

<p ><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; unsigned long max;&nbsp;&nbsp;&nbsp; /* size of the allocated array */&nbsp;</span></p>

<p ><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; phys_addr_t total_size;&nbsp;&nbsp;&nbsp; /* size of all regions */&nbsp;</span></p>

<p ><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; struct memblock_region *regions;&nbsp;</span></p>

<p ><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; char *name;&nbsp;</span></p>

<p ><span style="font-size:16px;">};</span></p>

<p >&nbsp;</p>

<p ><strong><span style="font-size:22px;">二伙伴分配器</span></strong></p>

<p ><span style="font-size:16px;">内核初始化完毕后,使用页分配器管理物理页,当前使用的页分配器是伙伴分配器,伙伴分配器的特点是算法简单</span></p>

<p align="left" ><span style="font-size:16px;">Memblock(引导内存分配器)完成对应的工作后,将未使用的内存释放至伙伴系统,完成伙伴系统的初始化工作。start_kernel()-&gt;mm_init()-&gt;mem_init()-&gt;memblock_free_all()。</span></p>

<p ><span style="font-size:16px;"> &nbsp;</span></p>

<p ><span style="font-size:16px;">伙伴系统是一个结合了2的方幂个分配器和空闲缓冲区合并计技术的内存分配方案。</span></p>

<p >&nbsp;</p>

<pre>
<code class="language-cpp">        typedef struct pglist_data {
                //... ...
                //存储与当前节点相关的内存区域数组
                struct zone node_zones;
                //MAX_ZONELISTS个备用区域数组
                struct zonelist node_zonelists;
                int nr_zones; /* 当前节点中填充的区域数量 */
                //... ...
        } pg_data_t;
       
        struct zonelist {
                struct zoneref _zonerefs;
        };
        struct zoneref {
                struct zone *zone;        /* Pointer to actual zone */
                int zone_idx;                /* zone_idx(zoneref-&gt;zone) */
        };
</code></pre>

<p><span style="font-size:16px;">网上大佬的分析:内存被分成含有很多页面的大块, 每一块都是2个页面大小的方幂。如果找不到想要的块, 一个大块会被分成两部分, 这两部分彼此就成为伙伴。其中一半被用来分配, 而另一半则空闲。这些块在以后分配的过程中会继续被二分直至产生一个所需大小的块。当一个块被最终释放时, 其伙伴将被检测出来, 如果伙伴也空闲则合并两者。</span></p>

<p >&nbsp;</p>

<p ><span style="font-size:22px;"><strong>三 块分配器</strong></span></p>

<p >&nbsp;</p>

<p ><span style="font-size:16px;">为了解决小块内存的分配问题,LINUX内核提供了块分配器,最早实现的块分配器是SLAB分配器。</span></p>

<p ><span style="font-size:16px;">因为上一个伙伴分配器,buddy是以页框为分配单元,那对于小于一页的内存需求又该如何处理呢,如果直接分配一页,就浪费了宝贵的内存空间,形成了内碎片。</span></p>

<p ><span style="font-size:16px;">SLAB分配器的作用不仅仅是分配小块内存,更重要的作用是针对经常分配和释放的对象充当缓存。</span></p>

<p ><span style="font-size:16px;">通用的内存缓存的编程接口</span></p>

<p ><span style="font-size:16px;"> &nbsp;</span></p>

<p ><span style="font-size:16px;"> &nbsp;</span></p>

Jacktang 发表于 2025-1-8 07:32

<p>bootmem和memblock在内存管理上区别比较大</p>

常见泽1 发表于 2025-1-12 10:44

Jacktang 发表于 2025-1-8 07:32
bootmem和memblock在内存管理上区别比较大

<p>是的 我也是刚学习到这个</p>
页: [1]
查看完整版本: 《Linux内核深度解析》第三章 内存学习笔记2