0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux进程的内存消耗和泄漏详解

书生途 来源:书生途 作者:书生途 2022-05-14 10:07 次阅读

内存消耗和泄漏

  • 进程的VMA
  • 进程内存消耗的4个概念: vss、rss、pss和uss
  • page fault的几种可能性, major 和 minor
  • 应用内存泄漏的解决方法
  • 应用内存泄漏的检测方法:valgrind 和 addresssanitizer

本节重点阐述 Linux的应用程序究竟消耗了多少内存?

一是,看到的内存消耗,并不一定是真的消耗。

二是,Linux存在大量的内存共享的情况。
动态链接库的特点:代码段共享内存,数据段写时拷贝。
把一个应用程序跑两个进程,这两个进程的代码段也是共享的。

当我们评估进程消耗多少内存时,就是指在用户空间消耗的内存,即虚拟地址在0~3G的部分,对应的物理地址内存。内核空间的内存消耗属于内核,系统调用申请了很多内存,这些内存是不属于进程消耗的。

进程的虚拟地址空间VMA

poYBAGJ-ZoSAXn1TAABu5WwG4Z0259.jpg

task_struct里面有个mm_struct指针, 它代表进程的内存资源。pgd,代表 页表的地址; mmap 指向vm_area_struct 链表。 vm_area_struct 的每一段代表进程的一个虚拟地址空间。vma的每一段,都可能是可执行程序的某个数据段、某个代码段,堆、或栈。一个进程的虚拟地址,是在0~3G之间任意分布的。

pYYBAGJ-ZoSAYInyAAEgNvLwiU4140.jpg

上图 提供三种方式,看到进程的VMA空间。pmap 3474其地址,size, 权限,通过以上的方式,可以看到进程的虚拟地址空间,分布在0~3G,任意一小段一小段分布的。应用程序运行起来,就是一堆各种各样的VMA。VMA对应着 堆、栈、代码段、数据段、等,不在任何段里的虚拟地址空间,被认为是非法的。

poYBAGJ-ZoWAKppBAACpvXNELgQ800.jpg

当指针访问地址时,落在一个非法的地址,即不在任何一个VMA区域。相当于访问一个非法的地址,这些虚拟地址没有对应的物理地址。应用程序收到page fault,查看原因,访问非法位置,返回segv。

在VMA的东西,不等于在内存。调malloc申请了100M内存,立马会多出一个100M的 VMA,代表这段vma区域有r+w权限。

应用程序访问内存,必须落在一个VMA里。其次,落在一个VMA里也不一定对。把100M的堆申请出来,100M内存页全部映射为0页。页表里每一页写的只读,页表和硬件对应,MMU只查页表。而在页表项中指向物理地址的权限是只读,所以在任何时候,去写其中任何一页,硬件都会发生缺页中断。

Linux 内核在缺页中断的处理程序,通过MMU寄存器读出发生page fault的地址和原因。发现此时page fault的原因是写一个页表里记录只读的物理地址,而vma记录的虚拟地址又是r+w,此时,linux会申请一页内存。同时把页表中的权限改为r+w。

总结:
Linux 内核通过VMA管理进程每一段虚拟地址空间和权限。一旦发生page fault,如果没有落在任何一个vma区域,会干掉。VMA的起始地址+size,用来限定程序访问的地址是否合法。VMA中每一段的权限,是来界定访问这段地址是否使用正确的方式访问。把所有的vma加起来,构成进程的虚拟地址空间,但这并不代表进程真实耗费的内存。拿到之后才是真实耗费的内存,RSS。耗费的虚拟内存,是VSS。

pYYBAGJ-ZoWAB9mRAAC8kOW-Vl0528.jpg


1、申请堆内存vma,第一次写,页表里的权限是R ,发生page fault,linux会去申请一页内存,此时把页表权限设置为 R+W。
2、内存访问落在空白非法区域,程序收到segv段错误。
3、代码段在VMA记录是R+X,此时如果对代码段执行写,程序会收到segv段错误。

【文章福利】小编推荐自己的Linux内核技术交流群:【865977150】整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!!

poYBAGJ-ZoWAfnjtAADZ9NmCySQ141.jpg

内核学习网站:

Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈-学习视频教程-腾讯课堂​ke.qq.com/course/4032547?flowToken=1040236

minor 和major 缺页

缺页,分为两种情况:主缺页 和次缺页。

主缺页 和次缺页,区别就是 申请内存时,是否需要读硬盘。前者需要。

如上图第4种情况,在代码段里执行时,出现缺页。linux申请一页内存,而且要从硬盘中读取代码段的内容,此时产生了IO,称为 major缺页。

无论是代码段还是堆,都是边执行边产生缺页中断,申请实际的内存给代码段,且从硬盘中读取代码段的内容到内存。这个过程时间比较长。

minor: malloc的内存,产生缺页中断。去申请一页内存,没有产生IO的行为。major缺页处理时间,远大于minor。

pYYBAGJ-ZoWAfBNwAACJx5wvbds660.jpg

vss、rss、pss和uss的区别

poYBAGJ-ZoWAKXSbAACZ-PvEwcw068.jpg
VSS - Virtual Set Size
RSS - Resident Set Size
PSS - Proportional Set Size
USS - Unique Set Size
ASAN - AddressSanitizer
LSAN - LeakSanitizer

如上图,中间是一根内存条。三个进程分别是1044,1045,1054, 每一个进程对应一个page table,页表项记录虚拟地址如何往物理地址转换。硬件里的寄存器,记录页表的物理地址。当linux做进程上下文切换时,页表也跟着一起切换。

pYYBAGJ-ZoWAALXWAAC2Kx1EUOU143.jpg

三个进程都需要使用libc的代码段:

VSS = 1 +2 +3
RSS = 4 +5 +6
PSS= 4/3 + 5/2 + 6 比例化的
USS= 6 独占且驻留的

工具:smem ,查看进程使用内存的情况。
一般来讲,进程使用的内存量,还是看PSS,强调公平性。看内存泄漏看USS 就好了。

内存泄漏 界定和检测方法

界定:连续多点采样法,随着时间越久,进程耗费内存越多。主要由内存申请和释放不是成对引起。RSS/USS曲线,观察方法:使用smem工具查看多次进程使用内存,USS使用量。

检查工具:
1、valgrind ,会跑一个虚拟机,运行时检查进程的内存行为。会放慢程序的速度。不需要重新编译程序。
2、addressanitizer,需要重新编译程序。编译时加参数,-fsanitize
gcc 4.9才支持,只会放慢程序速度2~3倍。

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    10990

    浏览量

    206733
  • 应用程序
    +关注

    关注

    37

    文章

    3136

    浏览量

    56389
  • 内存泄漏
    +关注

    关注

    0

    文章

    38

    浏览量

    9166
收藏 人收藏

    评论

    相关推荐

    Linux内存管理是什么,Linux内存管理详解

    Linux内存管理 Linux内存管理是一个非常复杂的过程,主要分成两个大的部分:内核的内存管理和
    的头像 发表于 05-11 17:54 5286次阅读
    <b class='flag-5'>Linux</b>的<b class='flag-5'>内存</b>管理是什么,<b class='flag-5'>Linux</b>的<b class='flag-5'>内存</b>管理<b class='flag-5'>详解</b>

    Linux内存泄漏检测实现原理与实现

    在使用没有垃圾回收的语言时(如 C/C++),可能由于忘记释放内存而导致内存被耗尽,这叫 内存泄漏。由于内核也需要自己管理内存,所以也可能出
    发表于 12-09 11:11 849次阅读

    Linux进程间如何实现共享内存通信

    这次我们来讲一下Linux进程通信中重要的通信方式:共享内存作为Linux软件开发攻城狮,进程间通信是必须熟练掌握的重要技能,而共享
    发表于 04-26 17:14 573次阅读

    细说Linux内存泄漏检测实现原理与实现

    在使用没有垃圾回收的语言时(如 C/C++),可能由于忘记释放内存而导致内存被耗尽,这叫 内存泄漏。由于内核也需要自己管理内存,所以也可能出
    发表于 07-03 09:22 336次阅读
    细说<b class='flag-5'>Linux</b><b class='flag-5'>内存</b><b class='flag-5'>泄漏</b>检测实现原理与实现

    Linux内核内存泄漏怎么办

    Linux内核开发中,Kmemleak是一种用于检测内核中内存泄漏的工具。
    发表于 07-04 11:04 591次阅读

    Linux下查询进程占用的内存方法总结

    今天浩道跟大家一篇关于运维牛人如何在Linux下挖出吃内存进程,可以说是相当干的一个运维技能了,一起看看吧!
    发表于 07-27 10:51 9205次阅读
    <b class='flag-5'>Linux</b>下查询<b class='flag-5'>进程</b>占用的<b class='flag-5'>内存</b>方法总结

    Linux进程间通信——使用共享内存

    Linux进程间通信——使用共享内存 图文详情见附件
    发表于 11-21 10:53

    Linux上对进程进行内存分析和内存泄漏定位

    Linux产品开发过程中,通常需要注意系统内存使用量,和评估单一进程内存使用情况,便于我们选取合适的机器配置,来部署我们的产品。Linux
    发表于 07-09 08:15

    Linux进程内存结构

    Linux操作系统采用虚拟内存管理技术,使得每个进程都有各自互不干涉的进程地址空间。该地址空间是大小为4GB的线性虚拟空间,用户所看到和接触到的都是该虚拟地址,无法看到实际的物理
    发表于 06-01 09:17 1352次阅读
    <b class='flag-5'>Linux</b>下<b class='flag-5'>进程</b>的<b class='flag-5'>内存</b>结构

    Linux:测试进程占用的虚拟内存大小

    Linux:测试进程占用的虚拟内存大小
    的头像 发表于 06-23 09:23 2636次阅读
    <b class='flag-5'>Linux</b>:测试<b class='flag-5'>进程</b>占用的虚拟<b class='flag-5'>内存</b>大小

    Linux内核内存泄漏怎么办?

    什么是内存泄漏: 程序向系统申请内存,使用完不需要之后,不释放内存还给系统回收,造成申请的内存被浪费. 发现系统中
    的头像 发表于 02-20 17:14 2251次阅读
    <b class='flag-5'>Linux</b>内核<b class='flag-5'>内存</b><b class='flag-5'>泄漏</b>怎么办?

    Linux内核源码分析-进程的哪些内存类型容易引起内存泄漏

    ; 应用程序正在运行时忽然被 OOM kill 掉了; 进程看起来没有消耗多少内存,但是系统内存就是不够用了; ……类似问题,很可能就是内存
    发表于 01-14 13:02 6次下载
    <b class='flag-5'>Linux</b>内核源码分析-<b class='flag-5'>进程</b>的哪些<b class='flag-5'>内存</b>类型容易引起<b class='flag-5'>内存</b><b class='flag-5'>泄漏</b>?

    什么是内存泄漏内存泄漏有哪些现象

    内存泄漏几乎是很难避免的,不管是老手还是新手,都存在这个问题,甚至 Windows 与 Linux 这类系统软件也或多或少存在着内存泄漏
    的头像 发表于 09-05 17:24 8940次阅读

    内存泄漏会产生哪些后果

    ,只释放了p1,没有释放p2,产生了内存泄漏内存泄漏会产生哪些后果? 随着程序运行时间越来越久,内存有分配没有释放,会使得
    的头像 发表于 11-10 15:06 393次阅读
    <b class='flag-5'>内存</b><b class='flag-5'>泄漏</b>会产生哪些后果

    线程内存泄漏问题的定位

    在下降。确定内存泄漏确实存在。top中可以显示多种形式内存,进而可以判断是那种泄漏。比如vss/rss/pss等。 确定哪个进程
    的头像 发表于 11-13 11:38 322次阅读
    线程<b class='flag-5'>内存</b><b class='flag-5'>泄漏</b>问题的定位