ToB企服应用市场:ToB评测及商务社交产业平台

标题: Linux内存管理(Linux内存架构,malloc,slab的实现) [打印本页]

作者: 忿忿的泥巴坨    时间: 昨天 08:16
标题: Linux内存管理(Linux内存架构,malloc,slab的实现)

媒介

本篇文章开始解说Linux的内存管理,深入相识内存管理有助于我们深入Linux底层逻辑,加强对Linux的学习和相识。
一、Linux进程空间内存分配

下面是一个32位的Linux进程空间内存排布具体的环境:

内核空间(1GB):内核空间是操作系统核心代码和数据的所在地区。这部分空间由操作系统内核独占,用于实行操作系统的使命,如操作系统的调理、内存管理、驱动步调和系统调用等。在内核空间中,全部的内核模块和驱动步调都运行,并可以直接访问硬件资源。
用户空间(3GB):用户空间是给用户步调运行的地区,其中包罗了应用步调的代码、数据和堆栈等。用户空间是被操作系统管理和分配的,用户步调在这个空间中运行,并通过系统调用与内核举行交互。用户空间中的进程无法直接访问内核空间中的数据和功能,而必须通过系统调用接口来哀求内核的服务。
在用户空间中,可以进一步细分差别的段:
1.代码段:存储可实行步调的指令,即步调的二进制代码。
2.数据段:存储全局变量和静态变量等数据。
3.堆区:用于动态分配内存,通过调用malloc()、new等函数实现。
4.栈区:用于存储函数调用时的局部变量和函数调用的上下文。
这种地点空间的分配方式可以提供对操作系统和应用步调的良好隔离,确保系统的稳定性和安全性。操作系统内核在内核空间中运行,可以对硬件资源举行直接访问和管理,而用户步调在用户空间中运行,通过系统调用接口与内核举行通信,实现各种操作和功能。
二、malloc的实现机理

当使用malloc函数时会调用到brk系统调用。
brk系统调用用于改变进程的数据段的竣事地点,从而调解进程的堆空间大小。当调用malloc函数时,它会向操作系统哀求一块指定大小的内存空间。操作系统会查抄当前的堆空间大小,并根据必要调解堆的竣事地点,以供新的内存分配。
malloc函数会调用brk系统调用来增加堆空间的大小,以顺应所需分配的内存大小。如果哀求的内存大小超过了当前堆空间的剩余大小,则操作系统会扩展堆空间,使其满足哀求。反之,如果哀求的内存大小较小,当前剩余的堆空间大概会被重新分割,并返回相应大小的内存块给malloc函数。
调用brk系统调用将会调用到下面的函数:
这个函数的主要作用是根据用户空间的哀求调解进程的数据段竣事地点,从而动态调解进程的堆空间大小。
  1. SYSCALL_DEFINE1(brk, unsigned long, brk)
  2. {
  3.         unsigned long retval;
  4.         unsigned long newbrk, oldbrk;
  5.         struct mm_struct *mm = current->mm;
  6.         struct vm_area_struct *next;
  7.         unsigned long min_brk;
  8.         bool populate;
  9.         if (down_write_killable(&mm->mmap_sem))
  10.                 return -EINTR;
  11. #ifdef CONFIG_COMPAT_BRK
  12.         /*
  13.          * CONFIG_COMPAT_BRK can still be overridden by setting
  14.          * randomize_va_space to 2, which will still cause mm->start_brk
  15.          * to be arbitrarily shifted
  16.          */
  17.         if (current->brk_randomized)
  18.                 min_brk = mm->start_brk;
  19.         else
  20.                 min_brk = mm->end_data;
  21. #else
  22.         min_brk = mm->start_brk;
  23. #endif
  24.         if (brk < min_brk)
  25.                 goto out;
  26.         /*
  27.          * Check against rlimit here. If this check is done later after the test
  28.          * of oldbrk with newbrk then it can escape the test and let the data
  29.          * segment grow beyond its set limit the in case where the limit is
  30.          * not page aligned -Ram Gupta
  31.          */
  32.         if (check_data_rlimit(rlimit(RLIMIT_DATA), brk, mm->start_brk,
  33.                               mm->end_data, mm->start_data))
  34.                 goto out;
  35.         newbrk = PAGE_ALIGN(brk);
  36.         oldbrk = PAGE_ALIGN(mm->brk);
  37.         if (oldbrk == newbrk)
  38.                 goto set_brk;
  39.         /* Always allow shrinking brk. */
  40.         if (brk <= mm->brk) {
  41.                 if (!do_munmap(mm, newbrk, oldbrk-newbrk))
  42.                         goto set_brk;
  43.                 goto out;
  44.         }
  45.         /* Check against existing mmap mappings. */
  46.         next = find_vma(mm, oldbrk);
  47.         if (next && newbrk + PAGE_SIZE > vm_start_gap(next))
  48.                 goto out;
  49.         /* Ok, looks good - let it rip. */
  50.         if (do_brk(oldbrk, newbrk-oldbrk) < 0)
  51.                 goto out;
  52. set_brk:
  53.         mm->brk = brk;
  54.         populate = newbrk > oldbrk && (mm->def_flags & VM_LOCKED) != 0;
  55.         up_write(&mm->mmap_sem);
  56.         if (populate)
  57.                 mm_populate(oldbrk, newbrk - oldbrk);
  58.         return brk;
  59. out:
  60.         retval = mm->brk;
  61.         up_write(&mm->mmap_sem);
  62.         return retval;
  63. }
复制代码
三、物理内存与假造内存

1.物理内存

物理内存是指计算机中现实存在的硬件内存。它是由RAM(Random Access Memory,随机存取内存)或其他类似的硬件组成的,用于存储正在实行的步调和数据。物理内存是直接与计算机的中央处理器(CPU)相连,提供快速、随机访问数据的能力。
2.假造内存

假造内存是操作系统提供的一种抽象概念。它扩展了可用的内存空间,使得步调可以使用比物理内存更大的地点空间。假造内存将步调所需的内存分为连续的地点空间块,称为假造地点空间。每个步调都有自己的假造地点空间,这使得每个步调能够以独立的方式实行,而不会互相干扰。
假造内存的工作原理是将部分步调和数据存储在物理内存中,而将不常用的部分保存在磁盘上的交换文件中。当步调必要访问假造内存中的某个地点时,操作系统会根据某种映射机制将假造地点转换为物理地点。这个过程被称为假造内存管理。通过这种方式,系统可以运行更多的步调,即使物理内存有限。
假造内存的主要优势之一是提供了更大的地点空间,以支持大型步调和多使命操作系统。它还可以通过将不常用的数据存储在磁盘上来节省物理内存的使用,并提供更好的内存管理和数据保护机制。
总结而言,物理内存是计算机现实的硬件内存,而假造内存是通过操作系统提供的抽象层面扩展的内存概念,使得步调能够使用比物理内存更大的地点空间,并提供更好的内存管理和保护机制。
四、磁盘和物理内存区别

物理内存和磁盘是差别的存储介质,它们在计算机系统中扮演差别的脚色和功能。物理内存用于临时存储当前正在实行的步调和数据,而磁盘用于长期存储文件和持久性数据。
五、页

在 Linux 操作系统中,“页”(Page)是内存管理中的一个告急概念,尤其是在假造内存管理中。操作系统通过页来管理物理内存和假造内存之间的映射,使得每个进程能够独立地使用其假造地点空间,而不直接操作物理内存。这种分页管理有助于实现内存保护、内存共享、内存映射文件等机制。
页的根本概念:

分页管理的核心概念:

Linux 中分页的实现:

在 Linux 操作系统中,假造内存管理采用了分页机制。具体来说,Linux 中有以下几个关键组件与分页管理密切相关:
总结:


分页和假造内存技能使得操作系统能够更高效、安全地管理内存,提高了系统的可伸缩性和稳定性。
六、搭档算法

搭档算法(Buddy Allocation System)是一种内存分配算法,主要用于动态内存管理,特殊是在操作系统中用来管理物理内存的分配和开释。它通过将内存块分成具有2的幂大小的地区,并通过将相邻的空闲块配对来实现高效的内存分配。
搭档算法的核心概念:

搭档算法的工作原理:

搭档算法的优缺点:

长处:

缺点:

搭档算法的实现:

在实现搭档算法时,通常使用一个位图(Bitmap)或者链表来管理每个内存块的空闲和占用状态。常见的实现方式如下:
例子:

假设内存的最小分配块为 16 字节,并且内存总量为 64 字节。在内存管理开始时,内存将被分别为多个 16 字节的块,形成一个空闲块链表。假设用户哀求了 24 字节的内存:
总结:

搭档算法是一个高效的内存分配和开释算法,通过将内存块分成 2 的幂大小的块,并通过合并相邻的空闲块来减少外部碎片。只管它存在肯定的内部碎片和管理复杂度,但在许多操作系统和内存管理系统中,它仍然是一种常用的内存分配策略。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4