Linux内存管理优化

简介: Linux内存管理优化

文件映射


文件映射通过映射虚拟内存的方式实现,在映射的时候进程访问的实际是文件对应的副本虚拟内存地址,既然访问虚拟内存位置可以完成文件的修改映射,那么直接访问物理内存也就是实际内存修改内容也是可行的。

通用:如果知道文件的具体地址,甚至可以直接定位到内存地址对于内容进行覆盖。


请求分页


进程向内核申请内存的通过请求分页的方式完成,之前提到过通过mmap的方式申请内存的方式虽然很方便,并且通常的内存分配方式有下面两种:

  • 物理内存的直接申请和分配,高效
  • 句柄分配的方式,也就是页表对于虚拟内存和实际内存映射之后再给进程

这两种分配方式都存在两个比较明显的问题,那就是分配的时候如果申请了却没有使用,会大量浪费,另外一次glibc一次需要超过进程的内存,可能出现一个很大的进程管理大量被申请未使用内存。

为了更好理解请求分页需要先理解分页的三种状态

  • 未分配页表和物理内存给进程。
  • 已分配页表但是未分配物理内存。
  • 已分配页表和物理内存。

为了解决分配浪费的问题,分配进程的内存仅使用一次分配方式,请求分页的核心是利用内核缺页中断的机制,当进程初次访问到已分配但是没有没有分配物理内存的空间,对于此时内核会进行缺页中断处理,同时给进程真正申请物理内存进行分配动作,这样可以保证每次分配内存的动作都是有效的。

这种方式也类似懒加载的方式,即可以保证分配动作运行,进程无感知缺页中断的情况,依然可以正常运行。

如果使用C语言按照请求分页的特点进行实验可以发现当内存没有使用的时候即使显示已经分配内存,但是实际可用物理内存没有变动。另外分配内存失败分为虚拟内存分配失败,物理内存分配失败,这是因为懒加载的设计导致的,另外虚拟内存不足不一定会导致物理内存不足,因为只要可用物理在分配时刻小于虚拟内存,那就是没法分配。


写时复制


写时复制是利用fork的函数提高虚拟内存分配效率,在文件系统的体现是update或者delete不会动原数据,而是用副本完成操作,当操作完成再更新引用,如果中间宕机断电,则用日志恢复状态即可。

在 Linux 系统的内存管理中调用 fork 系统调用创建子进程时,并不会把父进程所有占用的内存页复制一份,而是首先与父进程共用相同的页表,而当子进程或者父进程对内存页进行修改时才会进行复制 —— 这就是著名的 写时复制 机制。

写时复制的流程如下:

  • 在父进程调用fork的时候,并不是把所有内存复制给子进程 而是递交自己的页表给子进程。完成这一步如果子父进程只进行只读操作双方都会共享页表,但是一旦一方要改变数据,就会立马解除共享。
  • 在解除共享的时候会有如下操作
  • 由于写入失去权限,所以会出发缺页中断
  • 内核干预,执行缺页中断
  • 写入方的数据复制到另一处,并且把写入方的页表全部更新为新复制的内存并且赋予写入方写入权限,同时把之前共享的页表更新。而另一方则把这个刷新之后的页表重新连接即可。
  • 最后父子进程彻底写入权限和页表独立。但是之前解除共享的页表依然可以自由读写。

注意:fork调用的时候:并不会复制页表和内容,而是真正写入的时候会触发复制动作,这也是写时复制名字由来


交换内存


交换内存是Linux内核一种oom情况下的补偿机制,作用也是为了缓解内存溢出和不足的问题,交换内存的实现依靠的是虚拟内存的机制。简单理解就是在物理内存虽然不够,但是虚拟内存可以借用外部存储器也就是硬盘的一部分空间来充当物理内存使用,这一块分区叫做交换区,由于是借物理存储空间,这个操作也叫做换出。 另外如果借用的空间被释放则归还,这部分操作叫做换入,由于交换内存以页为单位,部分资料也叫页面调入和调出,都是一个意思。

成这一步如果只进行只读操作双方都会共享页表,但是一旦一方要改变数据,就会立马解除共享。

  • 在解除共享的时候会有如下操作
  • 由于写入失去权限,所以会出发缺页中断
  • 内核干预,执行缺页中断
  • 写入方的数据复制到另一处,并且把写入方的页表全部更新为新复制的内存并且赋予写入方写入权限,同时把之前共享的页表更新。而另一方则把这个刷新之后的页表重新连接即可。
  • 最后父子进程彻底写入权限和页表独立。但是之前解除共享的页表依然可以自由读写。

注意:fork调用的时候:并不会复制页表和内容,而是真正写入的时候会触发复制动作,这也是写时复制名字由来

另外交换内存很容易认为是一种扩充物理内存的美好方式,但是这里有一个本质的问题,那就是硬盘的访问速度和内存相比差的次方级别的差距。另外如果长期内存不足很容易导致交换内存不断的换入换出出现明显的性能抖动。

另外这类需要外部存储器的缺页中断在术语中被称之为硬性页缺失,相对的不需要外部存储器的页缺失是软性页缺失,虽然本质都是内核在触发和完整操作,但是硬性的缺失总归比软性缺失后果严重很多。

这里也要吐槽一下M1的各种偷硬盘缓存来提高性能的操作.....


多级页表


多级页表的设计核心是:避免把全部页表一直保存在内存中是多级页表的关键所在。特别是那些不需要的页表就不应该保留。

在X86-64架构当中,虚拟地址的空间大小约为128T,一个页的大小为4KB,页表的项目大小为8个字节。

所以一个进程的页表至少需要256GB内存!(8 * 128T / 4KB),但是我们都知道现在的电脑一般都是16GB内存为主,而32GB的内存虽然但是个人用的比较少。 那么系统应该如何维护页表?这就引入了多层页表来进行管理,多集页表可以从最简单的角度当作一个多级的指针看待,当然实际的多级页表一两句话是说不完的,这里我们可以大致理解多级页表是如何提升性能的?

首先我们可以思考,一个进程是否需要整个页表来管理内存?很显然是不需要的,这是引入多级页表的理由之一,可以发现绝大多数都不需要,比如一个进程需要12M空间,顶端需要4M,数据部分占用4M,底部又是一些堆栈内容和记录信息,在数据顶端上方和堆栈之间是大量根本没有使用的空闲区。

所以多级页表实际上就是大目录套小目录,和我们的一本书一样,小目录负责小的进程,而遇到比较大的进程就放到空闲页比较大的目录中完成分配操作,多级页表既可以高效的利用内存的同时,可以最大限度的减少页表本身的数据结构在内存的占用,同时上面的例子也可以发现绝大多数的进程其实根本不需要太大的页表进行维护和管理。

最后从网上的资料翻阅中发现一张下面的图,对于多级页表的理解有一定帮助:


网络异常,图片无法展示
|


最后X86_64 使用了4层的页表结构,直当理解就是四级指针,复杂程度可见一般。


标准大页


随着进程虚拟内存和页表的使用,进程使用的物理内存也会增加。

我们根据请求分页和写时复制的概念,可以发现当进程使用虚拟内存量增加会有一个明显的问题那就是在调用fork函数的时候会对于父子进程共享的页表进行拷贝,虽然这个拷贝动作不会占用物理内存,但是为进程复制操作需要拷贝一份完整的页表,所以当页表很大的时候,也会造成性能浪费。

为了解决这个问题,Linux提供了标准大页的机制,和他名字一样,就是比普通的页表更大的页,利用这种页表可以减小进程页表所需的内存使用量。

另外通过二级页表和标准大表可以有效的减少整个页表项的数量,最后对于标准大页我们只需要知道标准大页可以减少大量的虚拟内存进程的页表开支即可。


用法


C语言中使用mmap函数参数赋予 MAP_HUGETLB 标志,表示可以获取大页,但是更加常用的方式是使用程序允许使用使用标准大爷而不是这种手动切换的方式。

标准大页对于虚拟机和数据库等需要使用大量内存的应用程序是很有必要的,根据实际情况决定是否使用标准大页,通过这种设置可以减少这一类软件内存占用,还能提高fork效率。

透明大页透明大页是随着标准大页带来的附带特性,主要的作用是在连续的4KB页面如果符合指定条件就可以通过透明大页的机制转为一个标准大页,以及在不满足条件的时候会出现大页拆分为多个4KB页面的情况,所以这个机制


小结


这部分从文件映射的内容引申了Linux两个重要的机制:请求分页写时复制,目的本质上都是尽量减少进程对于内存的浪费,但是需要注意的是这两种方式都是使用了内核模式的系统中断机制来进行处理的,所以对于内核的性能以及稳定性要求非常高。

在之后的内容介绍了交换内存以及多级页表和标准大页几个内容,其中多级页表内部的细节非常的复杂,通常需要对于操作系统底层有比较熟悉的认知才能完全的了解这个页表的细节。

相关文章
|
1月前
|
机器学习/深度学习 算法 PyTorch
125_训练加速:FlashAttention集成 - 推导注意力优化的独特内存节省
2025年,大型语言模型的训练面临着前所未有的挑战。随着模型参数量和序列长度的不断增加,传统注意力机制的内存瓶颈问题日益突出。FlashAttention作为一种突破性的注意力算法,通过创新的内存访问模式和计算优化,显著提升了训练效率和内存利用。
|
1月前
|
存储 机器学习/深度学习 PyTorch
119_LLM训练的高效内存管理与优化技术:从ZeRO到Flash Attention
大型语言模型(LLM)的训练面临着前所未有的计算和内存挑战。随着模型规模达到数百亿甚至数千亿参数,高效的内存管理成为训练成功的关键因素之一。2025年,LLM训练的内存优化技术已经取得了显著进展,从ZeRO优化器到Flash Attention等创新技术,为训练超大规模模型提供了可能。
|
4月前
|
缓存 固态存储 Windows
如何让内存发挥到最大效能?全面优化指南,提升电脑运行体验
电脑内存使用不合理会导致卡顿,本文教你如何优化内存性能。检查内存容量与主板支持上限,考虑升级或调整配置;关闭后台程序、管理浏览器标签、结束异常进程以释放内存;设置虚拟内存、调整视觉效果、定期重启提升效率;必要时增加内存条、选择高频内存、更换固态硬盘。避免盲目清理内存和依赖大内存忽视其他硬件瓶颈。只需合理设置,无需额外花钱,就能显著提升电脑速度。
|
2月前
|
缓存 监控 Linux
Linux内存问题排查命令详解
Linux服务器卡顿?可能是内存问题。掌握free、vmstat、sar三大命令,快速排查内存使用情况。free查看实时内存,vmstat诊断系统整体性能瓶颈,sar实现长期监控,三者结合,高效定位并解决内存问题。
274 0
Linux内存问题排查命令详解
|
4月前
|
存储 人工智能 自然语言处理
AI代理内存消耗过大?9种优化策略对比分析
在AI代理系统中,多代理协作虽能提升整体准确性,但真正决定性能的关键因素之一是**内存管理**。随着对话深度和长度的增加,内存消耗呈指数级增长,主要源于历史上下文、工具调用记录、数据库查询结果等组件的持续积累。本文深入探讨了从基础到高级的九种内存优化技术,涵盖顺序存储、滑动窗口、摘要型内存、基于检索的系统、内存增强变换器、分层优化、图形化记忆网络、压缩整合策略以及类操作系统内存管理。通过统一框架下的代码实现与性能评估,分析了每种技术的适用场景与局限性,为构建高效、可扩展的AI代理系统提供了系统性的优化路径和技术参考。
251 4
AI代理内存消耗过大?9种优化策略对比分析
|
7月前
|
缓存 并行计算 PyTorch
PyTorch CUDA内存管理优化:深度理解GPU资源分配与缓存机制
本文深入探讨了PyTorch中GPU内存管理的核心机制,特别是CUDA缓存分配器的作用与优化策略。文章分析了常见的“CUDA out of memory”问题及其成因,并通过实际案例(如Llama 1B模型训练)展示了内存分配模式。PyTorch的缓存分配器通过内存池化、延迟释放和碎片化优化等技术,显著提升了内存使用效率,减少了系统调用开销。此外,文章还介绍了高级优化方法,包括混合精度训练、梯度检查点技术及自定义内存分配器配置。这些策略有助于开发者在有限硬件资源下实现更高性能的深度学习模型训练与推理。
1467 0
|
4月前
|
存储 人工智能 API
AI代理性能提升实战:LangChain+LangGraph内存管理与上下文优化完整指南
在AI代理系统开发中,上下文工程成为提升系统性能的关键技术。本文探讨了从提示工程到上下文工程的转变,强调其通过为AI系统提供背景信息和工具支持,显著提升智能化程度和实用价值。文章系统分析了上下文工程的理论基础、核心策略(如写入、选择、压缩和隔离),并结合LangChain和LangGraph工具,展示了如何实现上下文工程技术以优化AI代理性能。通过Scratchpad机制、内存管理、RAG系统集成、多代理架构及沙盒环境等技术手段,开发者可以更高效地构建高性能、可扩展的AI系统。
507 0
AI代理性能提升实战:LangChain+LangGraph内存管理与上下文优化完整指南
|
5月前
|
缓存 监控 Cloud Native
Java Solon v3.2.0 高并发与低内存实战指南之解决方案优化
本文深入解析了Java Solon v3.2.0框架的实战应用,聚焦高并发与低内存消耗场景。通过响应式编程、云原生支持、内存优化等特性,结合API网关、数据库操作及分布式缓存实例,展示其在秒杀系统中的性能优势。文章还提供了Docker部署、监控方案及实际效果数据,助力开发者构建高效稳定的应用系统。代码示例详尽,适合希望提升系统性能的Java开发者参考。
278 4
Java Solon v3.2.0 高并发与低内存实战指南之解决方案优化
|
3月前
|
边缘计算 算法 Java
Java 绿色计算与性能优化:从内存管理到能耗降低的全方位优化策略与实践技巧
本文探讨了Java绿色计算与性能优化的技术方案和应用实例。文章从JVM调优(包括垃圾回收器选择、内存管理和并发优化)、代码优化(数据结构选择、对象创建和I/O操作优化)等方面提出优化策略,并结合电商平台、社交平台和智能工厂的实际案例,展示了通过Java新特性提升性能、降低能耗的显著效果。最终指出,综合运用这些优化方法不仅能提高系统性能,还能实现绿色计算目标,为企业节省成本并符合环保要求。
152 0
|
5月前
|
存储 自然语言处理 算法
基于内存高效算法的 LLM Token 优化:一个有效降低 API 成本的技术方案
本文探讨了在构建对话系统时如何通过一种内存高效算法降低大语言模型(LLM)的Token消耗和运营成本。传统方法中,随着对话深度增加,Token消耗呈指数级增长,导致成本上升。
478 7
基于内存高效算法的 LLM Token 优化:一个有效降低 API 成本的技术方案