内存管理:虚拟地址空间和堆

news2025/1/20 12:00:30

准备用一个系列来总结一下内存管理涉及到的相关知识,范围从底层的数据结构和算法,到上层的API的使用,这里的内存管理,目前打算主要是侧重在堆的管理,本文作为一个引子,先粗略讲一下虚拟地址空间、堆管理、arena,接下来会陆续讲一下堆管理算法、malloc实现、new/delete等C++内容的相关实现等,但也希望如果以后有时间的话,也可以把栈和甚至和cache相关的内容也加到这个系列里,现在大概是这么规划的,不知道能写几篇,先努力写着看吧。

(免费订阅,永久学习)学习地址: Dpdk/网络协议栈/vpp/OvS/DDos/NFV/虚拟化/高性能专家-学习视频教程-腾讯课堂

一、虚拟地址空间

说内存管理,就必须要先说虚拟地址空间,这是现代程序运行的根本,基本概念大家都知道就不在这里赘述了,尽量把这部分的精华部分尽量简单的总结出来,先看一下进程虚拟地址空间的总体布局,以32位Linux系统为例:

图1

基于上图的虚拟地址空间布局来简单说下ELF文件是怎样映射到进程虚拟地址空间的,ELF文件被组织成如下图左列出的一系列section,其中具有相同属性(R/W/E)的section再组成一个segment,以segment为单位映射到进程的虚拟地址空间,其中虚拟地址空间中的segment要做到页大小对齐,下图也一同简要展示了虚拟地址空间到物理地址空间的映射,通过MMU完成,具体的细节请大家网上或者书上查资料,这都是比较基本的概念,这里就不赘述了:

图2

其它系统原理类似,都是将可执行程序组织成若干segment连同用到的动态库和kernel映射到进程的虚拟地址空间,主要差别在于不同segment映射的起始地址、大小不同等,比如32位Linux系统的Text segment起址是0x08048000,64位Linux系统的Text segment起址是0x00400000,再比如相对32位Linux系统的kernel space是1G,32位Windows的kernel space是2G等等,后面相关内容全部以32位Linux系统为例说明。

二、堆

从图1中可以看到堆所处的位置,它位于Data segment的上面,这部分堆空间是程序默认创建的,主要是给程序的主线程用的,在特定的情况下(比如malloc申请大内存的时候、多线程的时候等),堆的内容还会扩展到图1中的Memory mapping segment区域,假如一共存在三个堆区域,它们的分布如下图所示:

图3

应用申请堆空间,主要是通过三个系统函数完成的:brk、sbrk、mmap,在前面图3中,主线程的堆空间是用brk或者sbrk申请的,heap1和heap2这两个Memory mapping segment是用mmap申请的。其中brk和sbrk使用的是同一个系统调用,根本原理是改变上面图3中的brk ptr这个指针的位置,mmap的功能很强大,在申请堆空间的时候主要使用它的Anonymous mapping的功能,下面是一个从上到下的简略调用关系:

图4

在堆中,内存被管理的基本单位是块,glibc中的名字叫chunk,为了不引起歧义,这个系列以后全部用chunk这个词来表示堆中的内存块,如下图所示(其中的free chunk会用后续文章介绍的某种算法维护,这里没有画出):

图5

三、arena

很多人可能没听说过这个概念,这是Linux堆管理中常用的一个术语,这个词的意思是竞技场,感觉这个词用的非常传神,堆这块地方可不就是一个竞技场么。下面从glibc实现的角度简单说下arena,在glibc中,arena的个数是有限制的,限制条件如下:

systemarena number
32bit2 x cpu_core_number + 1
64bit8 x cpu_core_number + 1

每个线程一定对应一个arena,但是一个arena可以给多个线程使用,同时一个arena可以由一个或者多个图3中的堆区组成,它们之间的关系如下图:

图6

在glibc中,每一个heap的开始有一个heap_info的描述头(注意main thread所用到的那个arena对应的heap没有这个描述头,也就是紧挨着data segment的那个使用brk/sbrk来动态扩展的heap),定义如下:

// malloc/arena.c
typedef struct _heap_info {
  // Arena for this heap
  struct malloc_state *ar_ptr;
  // Previous heap
  struct _heap_info *prev;
  // Current size in bytes
  size_t size;
  // Size in bytes that has been mprotected PROT_READ|PROT_WRITE
  size_t mprotect_size;
  // padding
  char pad[];
} heap_info;

从上面代码可以看出,如果一个arena用到多个heap,那么这些heap通过prev这个指针连接起来,并且通过ar_ptr这个指针指向所属的arena,arena在glibc中对应的数据结构是malloc_state,定义如下:

// malloc/malloc.c
struct malloc_state {
  // Flags (formerly in max_fast)
  int flags;
  // Set if the fastbin chunks contain recently 
  // inserted free blocks, Note this is a bool 
  // but not all targets support atomics on booleans
  int have_fastchunks;
  // Fastbins
  mfastbinptr fastbinsY[NFASTBINS];
  // Base of the topmost chunk -- not otherwise kept in a bin
  mchunkptr top;
  // The remainder from the most recent split of a small request
  mchunkptr last_remainder;
  // Normal bins packed as described above
  mchunkptr bins[NBINS * 2 - 2];
  // Bitmap of bins
  unsigned int binmap[BINMAPSIZE];
  // Linked list
  struct malloc_state *next;
  // Linked list for free arenas.  
  struct malloc_state *next_free;
​
  // Number of threads attached to this arena
  INTERNAL_SIZE_T attached_threads;
  // Memory allocated from the system in this arena
  INTERNAL_SIZE_T system_mem;
  INTERNAL_SIZE_T max_system_mem;
};

这里只简单列一下和arena相关的两个数据结构,其中具体的字段含义等以后将malloc实现的时候再细说,这里先贴出来大家好有个基本概念。

四、reference

这个系列主要参考的资料有下面这些,后续的文章没有特殊情况的话就不再提及了,大家有兴趣的话也可以直接去翻看下面所述的章节:

  • 深入理解计算机系统:虚拟存储器这一章
  • 程序员的自我修养:可执行文件的装载与进程这一章
  • Effective C++:定制new和delete这一章
  • Modern Effective C++:Smart Pointers这一章
  • C++并发编程实战:C++内存模型和原子类型操作这一章
  • GCC的官方文档
  • cppreference的内存管理相关函数的manual
  • 网上的一些博文:
    • https://sploitfun.wordpress.com/2015/02/10/understanding-glibc-malloc/
    • https://sploitfun.wordpress.com/2015/02/11/syscalls-used-by-malloc
    • https://fantiq.github.io/2019/05/13/malloc%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90-%E5%88%9D%E5%A7%8B%E5%8C%96%E4%B8%8Earena%E7%9A%84%E5%88%9B%E5%BB%BA/
    • https://introspelliam.github.io/archives/
    • Safe-Linking - Eliminating a 20 year-old malloc() exploit primitive - Check Point Research
    • tcache 源码分析及利用思路

原文链接:https://zhuanlan.zhihu.com/p/374431199  原文作者:月踏

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

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

相关文章

​合并PDF文件什么方法很简单?看完你就明白了

想要将几个PDF文件合并到一起,什么方法使用起来是很简单的呢?PDF文件作为大家经常使用的文件之一,对它的编辑需求也很多,除了需要编辑文件的内容之外,还有需要将几个文件合并到一起使用的需求。那么我们如果遇到这种情…

traffic-forward

traffic-forward traffic-forward 是一款python开发的流量转发工具,可以使用python脚本行运行,也可以封装使用命令行,同样可以使用pyinstaller等工具进行封装成Macos,Linux, Windows 下的可执行文件运行,可用于本地流量…

简单理解HTML区块_HTML学习第七篇区块元素和内联元素

简单理解HTML区块_区块元素和内联元素HTML篇_第七章、区块一、区块元素和内联元素1.1块级元素1.2内联元素二、<div>元素三、<span>元素HTML篇_第七章、区块 一、区块元素和内联元素 HTML元素可以通过<div>和<span>元素组合起来&#xff0c;大多数 HT…

固定行数的纵向分栏

【问题】 what can ı configure the jasper report detail heapriider layout ? ı want to print datas side by side and every sides have 4 datas sub bottom 1 data1 5 data5 2 data2 6 data6 3 data3 4 data4 【回答】 整张报表纵向分栏可在 jasper 中设置分栏数&a…

性能高、上手快,实体类转换工具 MapStruct 到底有多强大

1.什么是MapStruct 1.1 JavaBean 的困扰 对于代码中 JavaBean之间的转换&#xff0c; 一直是困扰我很久的事情。在开发的时候我看到业务代码之间有很多的 JavaBean 之间的相互转化&#xff0c; 非常的影响观感&#xff0c;却又不得不存在。我后来想的一个办法就是通过反射&…

用Quasar开发Vue3+Electron跨平台应用的简单指南

1. 前言 Quasar是一个开源的vue.js基础框架&#xff0c;简单配置即可在其基础上进行SPA, SSR, PWA, 手机网站以及跨平台应用程序的开发&#xff0c;本文将简述如何基于Quasar Vue3 Vite Electron进行桌面应用开发。 2. 配置流程 2.1 框架构建 首先&#xff0c;在要存放代…

『NLP学习笔记』NER任务的CRF-layer的原理

NER任务的CRF-layer的原理 文章目录一. 预备工作二. BILSTM-CRF模型2.1. BiLSTM层输出2.2. 如果没有CRF层会怎么样2.3. CRF层可以从训练数据中学到约束三. CRF层3.1. 发射(Emission)分数3.2. 转移(Transition)分数3.3. CRF损失函数3.4. 实际路径得分3.5. 所有可能的路径的得分…

Ac-EEVVAC-pNA,389868-12-6

Ac-EEVVAC-pNA, chromogenic substrate for a continuous spectrophotometric assay of HCV NS3 protease. The sequence EEVVAC is derived from the 5A-5B cleavage junction of the HCV polyprotein. Ac-EEVVAC-pNA, HCV NS3蛋白酶连续分光光度法测定的显色底物。EEVVAC序列…

FPGA驱动24C04实现读写操作,提供工程源码和技术支持

目录1.24c04芯片手册解读2.纯verilog的i2c驱动3.24c04读写状态机设计4.上板调试验证5.福利&#xff1a;工程源码获取1.24c04芯片手册解读 24c04芯片手册很简单&#xff0c;原理图设计页很简单&#xff0c;这里只说代码设计需要注意的点&#xff1a; 1、写操作延时周期大于等于…

嵌入式软件工程师技能树——Linux应用编程+网络编程+驱动开发+操作系统+计算机网络

文章目录Linux驱动开发1、Linux内核组成2、用户空间与内核的通讯方式有哪些&#xff1f;3、系统调用read/write流程4、内核态用户态的区别5、bootloader内核 根文件的关系6、BootLoader的作用7、BootLoader两个启动阶段1、汇编实现&#xff0c;完成依赖于CPU体系架构的设置&…

推荐系统学习笔记--推荐系统简介

由来 互联网的出现和普及给用户带来了大量的信息&#xff0c;满足了用户在信息时代对信息的需求&#xff0c;但随着网络的迅速发展而带来的网上信息量的大幅增长&#xff0c;使得用户在面对大量信息时无法从中获得对自己真正有用的那部分信息&#xff0c;对信息的使用效率反而…

前三季度净亏损8.01亿元,亿咖通海外上市背后的「吉利阴影」

中国智能汽车产业链供应商正在通过SPAC方式在海外上市&#xff0c;或将成为新一轮资本浪潮的焦点。这些企业大多数已经具备一定规模&#xff0c;但仍处于亏损状态。 11月21日&#xff0c;亿咖通&#xff08;ECARX Holdings, Inc.&#xff09;宣布&#xff0c;之前与COVA Acqui…

Windows Terminal 快速配置 oh-my-posh

背景 想美化下windows terminal &#xff0c;选择了oh-my-posh。网上的文章有点多&#xff0c;加上官方的教程对初次使用着并不是太友好&#xff0c;所以自己快速摸索了。记录下过程。 步骤 1&#xff0c;安装oh-my-posh 打开以下链接&#xff0c;安装oh-my-posh Windows …

一个进程只能最多创建2000个线程吗?

我经常听到有人说&#xff0c;为什么不能创建一个包含2000个线程的进程。 原因不是Windows中固有的任何特定限制。相反&#xff0c;程序员没有考虑每个线程使用的地址空间量。 线程由内核模式下的一些内存&#xff08;内核堆栈和对象管理&#xff09;和用户模式下的一些内存&…

互动抽奖背后的随机性与算法实现

背景抽奖&#xff0c;是一种典型的互动玩法形式。无论是大V的粉丝抽奖&#xff0c;还是活动会场的参与抽奖&#xff0c;这种起源于彩票开奖的互动玩法&#xff0c;同时兼顾了高期待感和低预期的特征&#xff0c;让活动在成本控制之余又能有惊喜和引爆点&#xff0c;这样的优势让…

java毕业设计——基于java+Socket+sqlserver的远程监控系统软件设计与实现(毕业论文+程序源码)——远程监控系统

基于javaSocketsqlserver的远程监控系统软件设计与实现&#xff08;毕业论文程序源码&#xff09; 大家好&#xff0c;今天给大家介绍基于javaSocketsqlserver的远程监控系统软件设计与实现&#xff0c;文章末尾附有本毕业设计的论文和源码下载地址哦。 文章目录&#xff1a;…

安全智能分析技术 思路方案

思路方案 在安全领域的研究中我们发现&#xff0c;很多数据预处理的步骤&#xff0c;在不同的场景下中都可以相互 借鉴&#xff0c;甚至可以进行直接复用。例如&#xff0c;对于加密流量相关的数据&#xff0c;当算法工程师 获取到一批加密流量的 pcap 包之后&#xff0c;不论他…

【Linux学习】之将输出重定向到文件或程序

将输出重定向到文件或程序 文章目录将输出重定向到文件或程序1. 标准输入、标准输出和标准错误2. 输出重定向操作符2.1 用法及说明2.2 合并重定向运算符2.3 输出重定向示例2.4 输出重定向实例23. 构建管道3.1 含义3.2 管道示例1. 标准输入、标准输出和标准错误 进程使用称为文…

Ac-IYGEF-NH2,168781-78-0

Ac-IYGEF-amide, excellent small peptide substrate for the protein tyrosine kinase pp60c-src (Km 368 M and Vmax 1.02 mol min⁻ mg⁻). Ac-IYGEF-amide&#xff0c;蛋白酪氨酸激酶pp60c-src的优秀小肽底物(Km 368 μ M, Vmax 1.02 μ mol minmg)。 编号: 150669中文名称…

新冠“阳”后嗓子疼到只能喝粥?千万别错过这几条加速康复建议

你一定很熟悉这张传遍朋友圈的小照片。你周围的亲戚、朋友、同事&#xff0c;甚至你自己&#xff0c;可能已经变成了前几批“小阳人”&#xff0c;正在体验传说中的高热、肌痛、头痛、喉咙痛、持续咳嗽、食物不振、味觉和嗅觉丧失。此时此刻&#xff0c;每个人都想增加身体的战…