首页 > 系统相关 >图解Linux下C内存分配 by using gpt

图解Linux下C内存分配 by using gpt

时间:2024-12-25 14:41:22浏览次数:8  
标签:sbrk -- mmap Memory brk 内存 Linux gpt using

我们可以通过GPT来详细地图解Linux上的C内存分配。这个过程可以进一步细化,只要你愿意。

最小的 C 代码示例

以下代码使用了标准 C 库函数 malloc 分配一块内存:

#include <stdlib.h>
#include <stdio.h>

int main() {
    int *ptr = (int *)malloc(sizeof(int) * 10); // 分配10个整数大小的内存
    if (ptr == NULL) {
        perror("Memory allocation failed");
        return 1;
    }
    free(ptr); // 释放内存
    return 0;
}

系统调用的分叉情况

brk 和 sbrk 系统调用接口

brksbrk 是用于调整数据段(heap)大小的系统调用。以下是它们的接口说明:

brk

#include <unistd.h>

int brk(void *end_data_segment);
  • end_data_segment: 指向新的数据段末尾的指针。
  • 返回值: 成功时返回 0,失败时返回 -1 并设置 errno。

sbrk

#include <unistd.h>

void *sbrk(intptr_t increment);
  • increment: 增加或减少数据段大小的字节数。
  • 返回值: 成功时返回之前的程序 break 地址,失败时返回 (void *) -1 并设置 errno。

直接从 C 代码调用 brk 和 sbrk 的示例

#include <unistd.h>
#include <stdio.h>

int main() {
    void *initial_brk = sbrk(0); // 获取当前的程序 break 地址
    printf("Initial program break: %p\n", initial_brk);

    // 增加数据段大小
    if (sbrk(1024) == (void *) -1) {
        perror("sbrk failed");
        return 1;
    }

    void *new_brk = sbrk(0); // 获取新的程序 break 地址
    printf("New program break: %p\n", new_brk);

    // 恢复原来的数据段大小
    if (brk(initial_brk) == -1) {
        perror("brk failed");
        return 1;
    }

    printf("Program break reset to: %p\n", sbrk(0));
    return 0;
}

mmap 系统调用接口

mmap 是用于映射文件或设备到内存的系统调用。以下是它的接口说明:

#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
  • addr: 映射的起始地址,通常为 NULL 以让内核选择地址。
  • length: 映射的字节数。
  • prot: 内存保护标志,如 PROT_READPROT_WRITE 等。
  • flags: 映射选项,如 MAP_PRIVATEMAP_ANONYMOUS 等。
  • fd: 文件描述符,若使用匿名映射则为 -1。
  • offset: 文件映射的偏移量,通常为 0。
  • 返回值: 成功时返回映射区域的指针,失败时返回 MAP_FAILED 并设置 errno。

直接从 C 代码调用 mmap 的示例

#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

int main() {
    size_t length = 4096; // 映射 4KB 内存
    void *addr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (addr == MAP_FAILED) {
        perror("mmap failed");
        return 1;
    }

    printf("Memory mapped at address %p\n", addr);

    // 使用映射的内存
    int *array = (int *)addr;
    for (int i = 0; i < length / sizeof(int); i++) {
        array[i] = i;
    }

    // 取消映射
    if (munmap(addr, length) == -1) {
        perror("munmap failed");
        return 1;
    }

    return 0;
}

综合,malloc内部的分叉逻辑:

  1. 小内存块(例如几 KB):通过 brk 调整堆的大小。
  2. 大内存块(通常超过一定阈值,如 128 KB):通过 mmap 分配匿名内存区域。

用户态到内核态流程的 Mermaid 图

graph TD A[User Application] -->|malloc| B[glibc] B -->|small allocation| C[brk/sbrk] B -->|large allocation| D[mmap] C -->|System Call| E[Kernel: Adjust Heap] D -->|System Call| F[Kernel: Map Memory Pages] E --> G[Allocate Physical Memory] F --> G[Allocate Physical Memory]

内存分配的 Mermaid 图示

graph TD A[Heap Start] -->|Expand by brk/sbrk| B[Heap End] C[Anonymous Memory Region] -->|mmap| D[Virtual Address Space] E[Kernel Memory Manager] -->|Page Allocation| F[Physical Memory]

解释:

  1. Heap Start 和 Heap End 表示由 brk/sbrk 管理的堆区域。
  2. Anonymous Memory Region 是通过 mmap 分配的虚拟内存。
  3. Kernel Memory Manager 负责将虚拟地址映射到物理内存页。

最小程序加载后的内存分布示意图(演示brk/sbrk直接在Heap区域分配小内存)

graph TD H[Kernel Space] --> G[Stack] G --> F[Unmapped Memory] F --> E[Heap End] E -->|brk/sbrk| D[Heap Start] D --> C[Uninitialized Data Segment] C --> B[Initialized Data Segment] B --> A[Program Static Code Segment]

解释:

  1. Kernel Space:内核空间。
  2. Stack:存储函数调用的栈帧和局部变量。
  3. Unmapped Memory:未映射的内存区域。
  4. Heap Start 和 Heap End:由 brk/sbrk 管理的堆区域。
  5. Uninitialized Data Segment:存储未初始化的全局和静态变量(BSS段)。
  6. Initialized Data Segment:存储已初始化的全局和静态变量。
  7. Program Static Code Segment:存储程序的代码。

mmap 分配匿名内存区域的示意图

  1. Anonymous Memory Region 是通过 mmap 分配的虚拟内存。
  2. mmap 分配的内存区域不在 HEAP 区域内,因为 mmap 直接在虚拟地址空间中分配内存,而不依赖于堆的增长。堆的增长是通过 brk/sbrk 系统调用来管理的,而 mmap 则用于分配较大的内存块或特定用途的内存区域,如共享内存或文件映射。这样可以避免堆和 mmap 分配的内存区域相互干扰,提高内存管理的灵活性和效率。
graph TD H[Kernel Space] --> G[Stack End] G[Stack End] --> F[Stack Start] F[Stack Start] --> E[Unmapped Memory] E --> I[Anonymous Memory Region] I --> J[Unmapped Memory] J --> D[Heap End] D --> C[Heap Start] C --> B[Uninitialized Data Segment] B --> A[Program Static Code Segment]

解释:

  1. Stack Start 和 Stack End:表示栈的起始和结束位置。
  2. Anonymous Memory Region 是通过 mmap 分配的虚拟内存,位于栈和堆之间的未映射内存区域中。
  3. Heap Start 和 Heap End:由 brk/sbrk 管理的堆区域。
  4. Uninitialized Data Segment:存储未初始化的全局和静态变量(BSS段)。
  5. Initialized Data Segment:存储已初始化的全局和静态变量。
  6. Program Static Code Segment:存储程序的代码。

标签:sbrk,--,mmap,Memory,brk,内存,Linux,gpt,using
From: https://www.cnblogs.com/math/p/18630366/c-malloc-detail-in-linux

相关文章

  • Linux修改运行级别
    Linux修改运行级别​ 运行级别(runlevel)是指系统的工作状态或运行模式。每个运行级别都对应着一组特定的服务和进程,用于满足用户或系统的不同需求。通过更改运行级别,用户可以控制系统启动时所加载的服务和进程,从而实现定制化的系统配置。init级别systemctltarget说明0......
  • Linux:code:network:devinet_sysctl_forward;IN_DEV_FORWARD
    文章目录简介sysctl设置使用,arp_process间接使用IN_DEV_RX_REDIRECTSdev_disable_lro简介最近在看Linux里的forwarding的功能。顺便在这里总结一下。有些详细代码逻辑,如果可以记录一下,会好一点。sysctl设置这个函数在查看的时候需要注意的问题:变量名起的有......
  • 备忘<大模型>--gpt4all本地可部署
    1.下载安装包https://www.nomic.ai/gpt4all2.下载模型https://docs.gpt4all.io/gpt4all_desktop/models.html#example-modelshttps://blog.csdn.net/mc_dudu233/article/details/140988148(参考该博客成功)https://www.freedidi.com/11195.html(可直接下载的以gguf结尾的模型)https://......
  • selinux
      ps-eZ|greppidname   一个服务通过grpc访问一个服务报错avc:deniedscontext=system_u:system_r:init_t:s0tcontext=system_u;object_r:http_port_t:s0应该如何解决ps-eZ|grep<process_name> ausearch-mavc   selinuxscontext与tcont......
  • Linux(Centos 7.6)yum源配置
    yum是rpm包的管理工具,可以自动安装、升级、删除软件包的功能,可以自动解决软件包之间的依赖关系,使得用户更方便软件包的管理。要使用yum必须要进行配置,个人将其分为三类,本地yum源、局域网yum源、第三方yum源,其说明配置如下:1.本地yum源配置1.1.上传iso镜像文件连接Linux(Cento......
  • Linux(Centos 7.6)基本信息查看
    1.服务器硬件信息查看1.1.服务器厂商、产品名称查看dmidecode-ssystem-manufacturer:查看服务器厂商信息dmidecode-ssystem-product-name:查看服务器产品名称信息1.Windows使用VMware安装的Linux(Centos7.6)后,服务器厂商、产品名称信息查看。[root@localhost~]#dmide......
  • Linux复习2——管理文件系统1
    超级用户->普通用户:exit普通用户->超级用户:suLinux一般将文件可存取的身份分为三个类别,分别是owner/group/others,且三种身份各有read/write/execute等权限系统目录结构/——根目录/home、/root——用户的宿主目录/usr——命令程序文件/etc——配置文件/boot——系统......
  • 【Linux系列】获取当前目录
     ......
  • 【Linux系列】Linux 系统配置文件详解:`/etc/profile`、`~/.bashrc` 和 `~/.bash_profi
     ......
  • 腾讯通RTX平滑升级路径,支持Linux系统及移动端
    一、腾讯通RTX继续使用的主要难题随着腾讯通RTX停止更新并下架官网,用户不仅无法继续获得更新、技术支持和资源下载,还面临以下使用上的问题:●不兼容国产系统与移动端:腾讯通RTX仅支持Windows和Mac操作系统,无法运行在基于Linux内核的国产操作系统(如统信UOS、银河麒麟)及移动设备(如A......