`

pg的内存管理机制一:AllocSet的内存分配

 
阅读更多

1 AllocSet 的内存分配涉及到的方法和数据结构

话说

MemoryContextMethods 结构里的函数实现了pgAllocSetMemoryContext 的内存管理机制,定义见下面。

 

 

typedef struct MemoryContextMethods

{

     void    *(*alloc) (MemoryContext context, Size size);

     /* call this free_p in case someone #define's free() */

     void      (*free_p) (MemoryContext context, void *pointer);

     void    *(*realloc) (MemoryContext context, void *pointer, Size size);

     void      (*init) (MemoryContext context);

     void      (*reset) (MemoryContext context);

     void      (*delete ) (MemoryContext context);

     Size     (*get_chunk_space) (MemoryContext context, void *pointer);

     bool      (*is_empty) (MemoryContext context);

     void      (*stats) (MemoryContext context);

#ifdef MEMORY_CONTEXT_CHECKING

     void      (*check) (MemoryContext context);

#endif

} MemoryContextMethods;

 

 

 

 

 

 

 

其中alloc 由静态函数AllocSetAlloc() 实现,具体签名在下面。它实现了AllocSet 相关的内存分配机制。

static void * AllocSetAlloc(MemoryContext context, Size size)

在写AllocSet 内存分配机制之前,先看两个和内存分配与管理密切相关的结构 Allockblock AllockChunk ,这个 前面的文章http://beigang.iteye.com/blog/1266554和http://beigang.iteye.com/blog/1279177里已经 提到不 止一次了。

    Allockblock AllockChunk 都是内存里的块,AllockBlock 类型是AllockBlockData *AllocChunk 类型是AllockChunkData*AllocBlockAllocSetmalloc 分配的内存单元,包含着一到多个AllockChunkAllocChunk是 MemoryContextMethods.alloc 请求分配的内存单元,将来由MemoryContextMethods . free_p 释放,放到AllocSetfreelist 链表数组的大小合适的链表里,以后被MemoryContextMethods.alloc 再分配。

AllockBlockData AllockChunkData 的定义如下

 

 

 

 

 

typedef struct AllocBlockData

{

    AllocSet    aset;           /* aset that owns this block */

    AllocBlock  next;           /* next block in aset's blocks list */

    char        *freeptr;        /* start of free space in this block */

    char        *endptr;         /* end of space in this block */

} AllocBlockData;

 

typedef struct AllocChunkData

{

    /* aset is the owning aset if allocated, or the freelist link if free */

    void        *aset;

    /* size is always the size of the usable space in the chunk */

    Size        size;

#ifdef MEMORY_CONTEXT_CHECKING

    /* when debugging memory usage, also store actual requested size */

    /* this is zero in a free chunk */

    Size        requested_size;

#endif

} AllocChunkData;

 

2 AllocSetAlloc

下面就写 MemoryContextMethods.alloc 的实现者AllocSetAlloc() 这个函数。这个内存分配过程还是有点复杂的,下面先上个图,然后分块解读处理流程。

 


 

 

 

 

AllocSetAlloc 分配内存流程图

 

 

 

 

 

 

根据上面的图,按红紫蓝黄绿的顺序做简要分解,具体的还是看流程图吧,算法基本上都在图里面了。

先声明一点,TopMemoryContext 所用内存是用malloc 独立分的,其他的AllocSet 都是调用AllocSetAlloc 分得。

现在分解红色块。首先传进来要在其上分配内存的AllocSet 和请求的大小,如果请求大小没有超过AllocChunk 的最大大小8k ,就在该AllocSet 的空闲可用AllocChunk 链表数组freelist (后面分析这个freelist )合适大小的链表里找有没有可以使用的AllocChunk ,如果没有的话就把请求大小加上AllocChunk 的大小(图中的Q ),然后在AllocSetAllocBlock 链表blocks 里找,看blocks 有没有满足大小的可用block ,如果没有,就malloc 分配一块block 。红色块到此结束。

接下来是紫色块,在上面分配的block 里分一个AllocChunk ,然后把该chunk 作为MemoryContext 类型返回,至此就分得了一块内存。

    蓝色框里是如果请求的大小超过了AllocChunk 的最大值8k ,就malloc 分配一个请求大小的block ,将其加入AllockSetblocks 链表中。在这个block 里面分配一个chunk ,作为MemoryContext 类型返回。

    黄色框里是如果前面在AllocSetfreelist 链表数组中的合适的链表里找到了可用chunk ,就把该chunk 从链表中取出来,作为MemoryContext 类型返回。

    现在就剩绿色框了。绿色框是维护前面多次提到的freelist 链表数组的,现在是分析这个空闲AllocChunk 链表数组的时候了。先看这个freelistAllocSet 可分配的AllocChunk 的大小是从23 次方依次到213 次方字节,也就是从8 字节依次到8k 字节。这样做的好处是可以方便管理内存,要是按实际需求分配的话对于内存再分配是个很大的挑战,会造成内存浪费。结构图见下面。


AllocSet freelist 结构图

    绿色框里就是说如果在AllocSetAllocBlock 链表blocks 里找到了block ,但是该block 的可用空闲空间不够请求大小时就把空闲大小按213 次方到23 次方依次分成AllocChunk 加入到对应大小的freelist 链表数组中的链表里。到此绿色块完了,这个AllocSetAlloc 也结束了。

 

3 示例

    下面再用图例演示从TopMemoryContextAllocBlock 链表blocks 里一个block 分配一个AllockChunk 类型的变量chunk ,然后在chunk 上初始化ErrorContext 的例子。下图是只有一个AllocBlockTomMemoryContext 结构图


TopMemoryContextAllocBlock 链表blocks 里的block 中分配了一个AllockChunk 变量chunk ,就是图纸粉色的那一块。

 



 

ErrorContext 放在了新分的chunk 上。

 

 

 


 

 

 

  • 大小: 164.9 KB
  • 大小: 15.2 KB
  • 大小: 38.6 KB
  • 大小: 40.7 KB
  • 大小: 49.1 KB
0
1
分享到:
评论

相关推荐

    Linux内存管理机制文档

    - 需要通过内存分配和地址转换才能将其与逻辑地址联系起来。 - **作用**:内核虚拟地址主要用于内核内部的数据结构和其他用途。 **5. 低端内存与高端内存** - **定义**:低端内存和高端内存都是物理内存的一部分。...

    pg055axibridgepcie_055PG.com_055pg.com_www.055PG.COM_https//:055

    055PG.com_055pg.com_www.055PG.COM_https//:055"似乎是一个标识符,结合描述中的"AXI Memory Mapped to PCI Express (PCIe)",我们可以推测这可能是一份关于在系统设计中使用AXI(Advanced eXtensible Interface)...

    linux内存管理总结

    - 虚拟内存分配:虚拟内存分配主要由`mm/vmalloc.c`处理,它实现了动态内存分配,提供给进程虚拟地址空间。 - 物理内存页面分配:物理内存的分配代码位于`mm/page_alloc.c`,负责为进程分配实际的物理页面。 - ...

    Linux 内存管理系统:初始化

    - `setup_arch`接下来调用`init_bootmem`函数以初始化启动时的内存分配器。此分配器仅在系统启动过程中使用,用于为永久的内核数据分配内存。 - 这些由`bootmem`分配器分配的页被视为内核的一部分,它们在系统启动...

    Linux内存管理笔记

    Linux内存管理笔记详细介绍了...通过对存储器层次、UMA/NUMA架构、内存域划分、线性地址概念、页帧管理、多级页表和冷热页分配机制的学习,可以帮助开发者更好地管理Linux系统的内存资源,提高系统的性能和稳定性。

    内存管理 --- linux内存管理的介绍

    在后一种情况下,内存分配器需要找到一个4KB的空闲页框,并将其分配给进程。 2. **磁盘数据传输效率**:虽然4KB和4MB都是磁盘块大小的倍数,但在大多数情况下,4KB的页大小在主存和磁盘之间的数据传输上更为高效。 ...

    PostgreSQL中文手册9.2

    五、 pg_auth_members: pg_auth_members: pg_auth_members: pg_auth_members:pg_auth_members: pg_auth_members:pg_auth_members:pg_auth_members:pg_auth_members: .64 七、 pg_tablespace: pg_tablespace: pg_...

    Linux内存管理--Linux物理内存三级架构.pdf

    内存管理涉及的知识点非常广泛,包括但不限于内存分配策略、内存回收机制、交换空间(swap)的使用以及内存压缩技术等。在实际的操作系统运行中,内存管理器负责监控和调整系统的内存使用情况,确保系统资源得到合理...

    Linux内核分析与应用课件第4章(四)物理内存分配与回收机制(二).pdf

    Linux内核的内存管理是操作系统核心的一个重要组成部分,特别是在处理物理内存分配与回收时,内核需要高效且灵活地管理资源。本节主要探讨的是Linux内核如何在用户进程请求内存时,通过内核函数来分配和回收物理内存...

    GP pg_catalog查询.docx

    在PostgreSQL数据库系统中,`pg_catalog`是一个特殊模式,它包含了系统定义的表、视图和索引,用于存储数据库元数据。元数据是指关于数据的数据,例如表的结构、列信息、索引、约束、函数等。下面将详细讨论在`GP pg...

    [原创]JOS_lab2实验报告: 内存管理及异常初始化

    实验过程涵盖了对虚拟地址和物理地址转换的理解,分页机制的实现,以及内存分配算法的编写。通过这个实验,学生可以深入理解操作系统如何管理内存资源和处理运行时错误,这对于构建和优化操作系统至关重要。 这个...

    80386内存分页机制

    80386作为一款高性能的微处理器,引入了一系列先进的特性,其中内存分页管理机制是它的一个亮点。这一机制能够有效地实现线性地址到物理地址的转换,为系统提供了更强大的内存管理能力。 在80386的保护模式下,**...

    Linux内存管理实现的分析与研究.pdf

    在Linux 2.4内核中,内存管理采用了非一致存储器访问(NUMA)模型,考虑到不同CPU对内存访问的时间差异,将内存划分到不同的节点(node),每个节点由Pg-data-t类型的描述符表示。每个节点的内存被进一步划分为三个...

    基于exec函数族分析Linux初始化进程运行环境的过程

    这样的划分方式有助于提高内存分配和管理的效率。 - **内存描述符(mm_struct)**:进程的内存描述符是包含与进程地址空间相关所有信息的数据结构。其中一些关键字段包括指向内存区域对象列表的指针、指向页目录的...

    操作系统实验报告Lab2物理内存管理(含challenge).docx

    - **slab分配器**是一种高效的内存分配机制,简化了slab中的数据结构。 - **cache_chain**:连接所有slab缓存的链表,方便best-fit算法寻找适合的分配大小。 - **kmem_cache**:定义一个特定大小的对象池,直接...

    pg150-ultrascale-memory-ip.pdf

    Xilinx公司的“pg150-ultrascale-memory-ip.pdf”文档提供了一份关于基于UltraScale架构的FPGA中使用的内存接口IP(Intellectual Property,知识产权)的详细指导手册。本文将详细介绍该文档中所涉及的关键知识点。 ...

    PostgreSQL 架构介绍1

    2. **内存分配**:分配内存资源,包括共享内存和本地内存。 3. **启动后台进程**:包括写入日志、监听客户端连接请求等。 ##### 3.2 进程 - **服务器进程**:负责接收客户端请求并分发工作。 - **backend process*...

    PgAdmin4安装包

    PgAdmin4是一款开源的图形化管理工具,专为PostgreSQL数据库管理系统设计,用于简化数据库的管理和开发。它提供了直观的用户界面,使得非编程背景的用户也能方便地执行常见的数据库操作,如创建、编辑和管理数据库...

Global site tag (gtag.js) - Google Analytics