Linux 上内存分配的工作原理

了解 linux 内存分配的细节非常重要,尤其是在内核和系统架构中。让我们深入了解 linux 内存分配并了解幕后发生的事情。

在计算机中,要使进程可执行,就需要将其放置在内存中。为此,必须将字段分配给内存中的进程。内存分配是一个需要注意的重要问题,尤其是在内核和系统架构中。

让我们详细了解一下 Linux 内存分配,并了解幕后发生的事情。

内存分配是如何完成的?

大多数软件工程师不知道这个过程的细节。但如果你是一名系统程序员候选人,你应该对它了解更多。在看分配过程的时候,有必要对 Linux 和glibc库做一个小细节。

当应用程序需要内存时,它们必须从操作系统请求它。来自内核的这个请求自然需要系统调用。您不能在用户模式下自己分配内存。

**malloc()**系列函数负责 C 语言中的内存分配。这里要问的问题是 malloc() 作为 glibc 函数是否进行直接系统调用。

Linux 内核中没有称为 malloc 的系统调用。但是,对于应用程序的内存需求有两个系统调用,它们是brkmmap

由于您将通过 glibc 函数在应用程序中请求内存,您可能想知道此时 glibc 正在使用哪些系统调用。答案是两者兼而有之。

Linux 上内存分配的工作原理

第一个系统调用:brk

每个进程都有一个连续的数据字段。通过 brk 系统调用,增加了决定数据域限制的程序中断值,并执行了分配过程。

尽管使用这种方法分配内存非常快,但并不总是可以将未使用的空间返回给系统。

例如,假设您通过 malloc() 函数为 brk 系统调用分配了五个字段,每个字段大小为 16KB。当您完成其中第二个字段时,无法返回相关资源(解除分配)以便系统可以使用它。因为如果您减少地址值以显示第二个字段的开始位置,并调用 brk,您将完成第三、四个和五个字段的释放。

为了防止这种情况下的内存丢失,glibc 中的 malloc 实现会监控进程数据字段中分配的位置,然后通过 free() 函数指定将其返回给系统,以便系统可以将空闲空间用于进一步的内存分配。

也就是说,在分配了 5 个 16KB 的区域之后,如果用 free() 函数返回第二个区域,过一段时间再请求另一个 16KB 的区域,而不是通过 brk 系统调用扩大数据区域,之前的地址是回来。

但是,如果新请求的区域大于 16KB,则数据区域将通过 brk 系统调用分配新区域来扩大,因为区域 2 无法使用。虽然二号区域没有使用,但由于大小不同,应用程序无法使用它。因为这样的场景,有一种情况叫做内部碎片,实际上你很少能充分利用内存的所有部分。

为了更好地理解,请尝试编译并运行以下示例应用程序:

#include #include #include int main(int argc, char* argv[]){        char *ptr[7];        int n;        printf("Pid of %s: %d", argv[0], getpid());        printf("Initial program break   : %p", sbrk(0));        for(n=0; nprintf("After 5 x 16kB malloc   : %p", sbrk(0));        free(ptr[1]);        printf("After free of second 16kB       : %p", sbrk(0));        ptr[5] = malloc(16 * 1024);        printf("After allocating 6th of 16kB    : %p", sbrk(0));        free(ptr[5]);        printf("After freeing last block        : %p", sbrk(0));        ptr[6] = malloc(18 * 1024);        printf("After allocating a new 18kB     : %p", sbrk(0));        getchar();        return 0;}

登录后复制

运行应用程序时,您将获得类似于以下输出的结果:

Pid of ./a.out: 31990Initial program break   : 0x55ebcadf4000After 5 x 16kB malloc   : 0x55ebcadf4000After free of second 16kB       : 0x55ebcadf4000After allocating 6th of 16kB    : 0x55ebcadf4000After freeing last block        : 0x55ebcadf4000After allocating a new 18kB     : 0x55ebcadf4000

登录后复制Linux 上内存分配的工作原理

带有 strace 的 brk 的输出如下:

brk(NULL)                               = 0x5608595b6000brk(0x5608595d7000)                     = 0x5608595d7000

登录后复制

如您所见,0x21000 已添加到数据字段的结束地址。您可以从值 0x5608595d7000 中理解这一点。因此分配了大约 0x21000 或 132KB 的内存。

这里有两点需要考虑。第一种是分配超过示例代码中指定的数量。另一个是哪一行代码导致了提供分配的 brk 调用。

地址空间布局随机化:ASLR

当您一个接一个地运行上述示例应用程序时,您每次都会看到不同的地址值。以这种方式随机更改地址空间会使安全攻击的工作变得非常复杂,并提高了软件的安全性。

但是,在 32 位架构中,通常使用 8 位来随机化地址空间。增加位数将不合适,因为剩余位上的可寻址区域将非常低。此外,仅使用 8 位组合不会使攻击者的事情变得足够困难。

另一方面,在 64 位体系结构中,由于可以为 ASLR 操作分配的位太多,因此提供了更大的随机性,并且提高了安全程度。

Linux 内核还支持基于 Android 的设备,并且 ASLR 功能在 Android 4.0.3 及更高版本上完全激活。即使仅出于这个原因,也可以说 64 位智能手机比 32 位版本具有显着的安全优势。

通过使用以下命令暂时禁用 ASLR 功能,之前的测试应用程序每次运行时都会返回相同的地址值:

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

登录后复制

要将其恢复到以前的状态,在同一个文件中写入 2 而不是 0 就足够了。

第二个系统调用:mmap

mmap 是 Linux 上用于内存分配的第二个系统调用。通过 mmap 调用,内存中任何区域的空闲空间都映射到调用进程的地址空间。

在以这种方式完成的内存分配中,当您想使用前面 brk 示例中的 free() 函数返回第二个 16KB 分区时,没有机制可以阻止此操作。从进程的地址空间中删除相关的内存段。它被标记为不再使用并返回系统。

因为与使用 brk 相比,使用 mmap 的内存分配非常慢,所以需要分配 brk。

使用 mmap,内存的任何空闲区域都映射到进程的地址空间,因此在该进程完成之前,已分配空间的内容被重置。如果没有以这种方式进行重置,则属于先前使用相关内存区域的进程的数据也可以被下一个不相关的进程访问。这样就不可能谈论系统中的安全性。

Linux 中内存分配的重要性

内存分配非常重要,尤其是在优化和安全问题上。如上面的示例所示,不完全理解此问题可能意味着破坏系统的安全性。

甚至许多编程语言中存在的类似于 push 和 pop 的概念也是基于内存分配操作的。能够很好地使用和掌握系统内存对于嵌入式系统编程和开发安全和优化的系统架构都是至关重要的。

如果您还想涉足 Linux 内核开发,请考虑首先掌握 C 编程语言。

综上所述,Linux 中的内存分配是一个需要注意和理解的重要问题,特别是对于程序员、内核开发人员和系统架构师而言。熟练掌握内存分配可以提高软件性能和安全性,并在嵌入式系统编程和系统架构方面提供更好的支持。同时,C 编程语言的掌握也是涉足 Linux 内核开发的关键。

以上就是Linux 上内存分配的工作原理的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2204131.html

(0)
上一篇 2025年2月26日 00:53:32
下一篇 2025年2月19日 02:02:46

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • pycharm怎样新建txt

    PyCharm创建txt文件步骤:打开项目资源管理器,右键单击文件夹,选择“新建”>“文件”。输入文件名称,确保扩展名为“.txt”。单击“确定”创建文件。保存文件:按Ctrl+S(Windows/Linux)或Cmd+S(macOS…

    2025年2月26日
    200
  • python软件下载

    Python 的官方下载方式为访问 Python 官方网站并根据操作系统下载对应版本。其他下载选项包括 PyPI 和第三方存储库,可能提供附加功能或预先安装的库。 Python 软件下载指南 如何下载 Python 下载 Python 的官…

    2025年2月26日
    200
  • python代码复制快捷键

    Python 快捷键:复制当前行:Windows/Linux:Ctrl + C;macOS:Cmd + C复制多行:按住 Shift 键,选择行,按 Ctrl + C (Windows/Linux) 或 Cmd + C (macOS)粘贴代…

    2025年2月26日
    200
  • 怎么用pycharm打开一个py文件

    如何在 PyCharm 中打开 .py 文件:打开 PyCharm;选择「文件」->「打开」,浏览并选择 .py 文件,单击「打开」;.py 文件将在编辑器区域中打开。还可通过拖放或使用快捷键 Ctrl+O (Windows/Linu…

    2025年2月26日
    200
  • pycharm环境配置错误怎么改正

    解决PyCharm环境配置错误的步骤:检查Python解释器路径是否正确配置。安装必要的Python库。检查环境变量中是否包含Python解释器和库路径。重新加载项目以应用更改。更新PyCharm至最新版本。如果以上方法无效,重置PyCha…

    2025年2月26日
    200
  • pycharm怎么添加虚拟环境

    在 PyCharm 中添加虚拟环境可隔离项目与系统 Python 环境:创建虚拟环境:创建新项目,在“项目解释器”中添加虚拟环境并设置名称和位置。激活虚拟环境:选择新创建的虚拟环境并点击“激活”。安装依赖项:在终端中使用 pip 命令安装依…

    2025年2月26日
    200
  • pycharm如何重新配置路径

    PyCharm 中更改路径需要:(1) 打开“Settings”(设置)窗口;(2) 选择“Project Interpreter”(项目解释器);(3) 移除旧路径;(4) 添加新路径;(5) 设置新路径为默认;(6) 重新加载项目。 如…

    2025年2月26日
    200
  • pycharm库文件在哪个文件夹

    PyCharm 库文件存储于以下文件夹:Windows:%APPDATA%JetBrainsPyCharmpluginsmacOS:~/Library/Application Support/JetBrains/PyCharm/plugin…

    2025年2月26日
    200
  • pycharm临时文件在哪

    针对不同操作系统,PyCharm 临时文件的存储位置为:Windows:%TEMP%JetBrainsPyCharmCEmacOS:~/Library/Caches/JetBrains/PyCharmCE/Linux:~/.cache/Je…

    2025年2月26日
    200
  • pycharm安装包在哪里看

    PyCharm安装包可从官方网站下载或通过JetBrains工具箱、SPM等渠道获取。下载的安装包是一个可执行文件,通常位于“下载”文件夹中,安装前需确保满足系统要求。 PyCharm安装包获取方式 官方网站下载 访问PyCharm官方网站…

    2025年2月26日
    200

发表回复

登录后才能评论