Linux内核之内存3: 进程的内存消耗和内存泄漏 布满荆棘的人生 2022-12-01 14:04 337阅读 0赞 ## 1.进程的VMA ## ### (1)进程地址空间 ### 在Linux系统中,每个进程都有自己的虚拟内存空间0~3G; 内核空间只有一个3G~4G; ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-htaZj4ZA-1598499510613)(media/39176a76208129a24056fa3f9bf23e04.jpg)\]][img-htaZj4ZA-1598499510613_media_39176a76208129a24056fa3f9bf23e04.jpg] 进程通过系统API调用,在内核空间申请内存,不统计在任何用户进程;进程消耗内存,单指用户空间内存消耗; ### (2)VMA列表 ### LINUX用task\_struct来描述进程,其中的mm\_struct是描述内存的结构体,mm\_struct有一个vma列表,管理当前进程的所有vma段。 ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7HypcM2V-1598499510616)(media/c0e4305d1d352443eb995b58eaf1e6b1.png)\]][img-7HypcM2V-1598499510616_media_c0e4305d1d352443eb995b58eaf1e6b1.png] 每个进程的内存由多个vma段组成: ### (3)查看VMA方法: ### #### **1.pmap** #### ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fn0VqW9K-1598499510617)(media/13ccc825d7e11b6e9345534002a6bf25.png)\]][img-Fn0VqW9K-1598499510617_media_13ccc825d7e11b6e9345534002a6bf25.png] 由图知,从接近0地址开始,第一个4K是只读代码段,第二个4K是只读数据段,还有其他共享库代码段,堆栈等; 可见一个进程的VMA涵盖多个地址区域\*\*,但并没有覆盖所有地址空间\*\*。VMA未覆盖的地址空间是illegal的,访问这些地址,缺页中断,发生pagefault. #### **2.cat /proc/pid/maps** #### ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XrGeAQWP-1598499510619)(media/200b79c79bbed7cc3bf79b82455a09c5.png)\]][img-XrGeAQWP-1598499510619_media_200b79c79bbed7cc3bf79b82455a09c5.png] 读文件形式,与pmap一一对应; #### **3.cat /proc/pid/smaps** #### 更详细的描述 00400000-00401000 r-xp 00000000 08:15 20316320 /home/leon/work/linux/mm/a.out Size: 4 kb KernelPageSize: 4 kB MMUPageSize: 4 kB Rss: 4 kB Pss: 4 kB Shared_Clean: 0 kB Shared_Dirty: 0 kB Private_Clean: 4 kB Private_Dirty: 0 kB Referenced: 4 kB Anonymous: 0 kB LazyFree: 0 kB AnonHugePages: 0 kB ShmemPmdMapped: 0 kB Shared_Hugetlb: 0 kB Private_Hugetlb: 0 kB Swap: 0 kB SwapPss: 0 kB Locked: 0 kB VmFlags: rd ex mr mw me dw sd 查看VMA的三个方法对比 ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KnPLug2c-1598499510620)(media/fbe52107869af6ec71998a87b12c39c2.png)\]][img-KnPLug2c-1598499510620_media_fbe52107869af6ec71998a87b12c39c2.png] VMA的来源,代码段,数据段,堆栈段。 ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9BwwyJtZ-1598499510623)(media/1d4cbcb84b83d8eb509049e88dfcda9f.png)\]][img-9BwwyJtZ-1598499510623_media_1d4cbcb84b83d8eb509049e88dfcda9f.png] **VMA是linux最核心数据结构之一。** ## 2.page fault的几种可能性,major和minor ## ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aAZ9dkmy-1598499510624)(media/b7e5bf2c1ad0ec776d99dfc99c90528d.png)\]][img-aAZ9dkmy-1598499510624_media_b7e5bf2c1ad0ec776d99dfc99c90528d.png] mmu给cpu发page fault时,可以从寄存器读到两个元素,**pagefault地址**,**pagefault原因**。 (1)访问Heap堆(首次申请,不是从Libc获取),第一次写,发生pagefault,linux检查VMA权限,发现权限合法,发缺页中断,申请一页内存,并更新页表。 (2)访问空区域,访问非法,发段错误; (3)访问代码段, 在此区域写,报pagefault,检查权限发现错误,报段错误; (4)访问代码段,在此区域读/执行,linux检查权限合法,若代码不在内存,那么申请内存页,把代码从硬盘读到内存。 伴随I/O的pagefault, 叫major pagefault, 否则minor pagefault. major pagefault耗时远大于 minor pagefault. \time -v python hello.py **3.内存是如何被瓜分的:** :vss、rss、pss和uss rss是不是代表进程的内存消耗呢,NO。 ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0NvPPmfQ-1598499510625)(media/6073a13855c3d6c6f0334b953cd7f285.png)\]][img-0NvPPmfQ-1598499510625_media_6073a13855c3d6c6f0334b953cd7f285.png] **VSS**:单个进程全部可访问的地址空间,但未必所有虚拟地址都已经映射物理内存; **RSS**:驻留内存,单个进程实际占用的物理内存大小(不十分准确的描述);上图的进程1 **PSS**: 比例化的内存消耗,相对RSS,将共享内存空间按被共享进程数量比例化;上图的C库4被三个进程共享,所以4/3; **USS**:进程独占内存,比如上图的堆6。 案例,连续运行两次a.out,查看内存占用情况 运行程序a.out ./a.out & pidof a.out cat /proc/pid/smaps |more ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gPyKvrtv-1598499510627)(media/5280f46620090ef6c3fa837ef5fbdfbe.png)\]][img-gPyKvrtv-1598499510627_media_5280f46620090ef6c3fa837ef5fbdfbe.png] ./a.out & pidof a.out ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7SXvN81O-1598499510628)(media/552b45603d10618e2d7b0809e91253b3.png)\]][img-7SXvN81O-1598499510628_media_552b45603d10618e2d7b0809e91253b3.png] cat /proc/pid_2/smaps |more PSS变化 shared\_clean private\_clean ## 4.应用内存泄漏的界定方法 ## ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LlsupTTy-1598499510628)(media/5835a1555e4cb021132a1d4826cc318c.png)\]][img-LlsupTTy-1598499510628_media_5835a1555e4cb021132a1d4826cc318c.png] 统计系统的内存消耗,查看PSS。 检查有没有内存泄漏,检查USS ./smem smem –pie=command ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2mmpCFRL-1598499510629)(media/988c1868230625fb4282deb0ff7e70c7.png)\]][img-2mmpCFRL-1598499510629_media_988c1868230625fb4282deb0ff7e70c7.png] smem –bar=command ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oGbvhuSh-1598499510630)(media/64ac61c220baae25eb3ee449ad3bbc89.png)\]][img-oGbvhuSh-1598499510630_media_64ac61c220baae25eb3ee449ad3bbc89.png] ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gQaQFVYl-1598499510631)(media/40574a9d8e29e2f10c507ed96a5c1b4e.png)\]][img-gQaQFVYl-1598499510631_media_40574a9d8e29e2f10c507ed96a5c1b4e.png] ### android里面有类似的工具,procmem/procrank ### smem分析系统内存使用是通过/proc/smaps的,procrank是通过分析/proc/kpagemap。 ## 5.应用内存泄漏的检测方法:valgrind和addresssanitizer ## 其他查询内存泄漏工具: valgrind: gcc -g leak-example.c -o leak-example valgrind --tool=memcheck --leak-check=yes ./leak-example ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UKodxfIp-1598500052901)(media/8323ab1eb838a435ddc6f82f731969ed.png)\]][img-UKodxfIp-1598500052901_media_8323ab1eb838a435ddc6f82f731969ed.png] 20468 HEAP SUMMARY: 20468 in use at exit: 270,336 bytes in 22 blocks 20468 total heap usage: 44 allocs, 22 frees, 292,864 bytes allocated 20468 20468 258,048 bytes in 21 blocks are definitely lost in loss record 2 of 2 20468 at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload\_memcheck-amd64-linux.so) 20468 by 0x4005C7: main (leak-example.c:6) ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uYOsWPOa-1598500052903)(media/06e725b77df25e31fdb09166e84dd4e1.png)\]][img-uYOsWPOa-1598500052903_media_06e725b77df25e31fdb09166e84dd4e1.png] valgrid是在虚拟机跑APP,速度很慢; **新版gcc4.9以后集成了asan** asan: gcc -g -fsanitize=address ./leak-example.c gcc -fuse-ld=gold -fsanitize=address -g ./lsan.c ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aRxm0vzE-1598500052905)(media/79984ebb28cbf21cd21690b20aa13ddd.png)\]][img-aRxm0vzE-1598500052905_media_79984ebb28cbf21cd21690b20aa13ddd.png] \#1 0x40084e in main lsan.c:9 内存泄漏不一定在用户空间,排查内核空间,检测slab , vmalloc slaptop, 检查申请和释放不成对。 在内核编译,打开kmemleak选项。 **5.工程调试内存泄漏问题一般步骤:** (1) meminfo, free 多点采样确认有内存泄漏。 (2)定位,smem检查用户空间 ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zj9u8ip1-1598500174678)(media/66e0b0b993fdacac3ac33583aec70b62.png)\]][img-zj9u8ip1-1598500174678_media_66e0b0b993fdacac3ac33583aec70b62.png] USS在不断增加。 (3) slab,检查内核空间。 cat /proc/slabinfo 其他查看内存信息的方法 cat /proc/meminfo cat /proc/buddyinfo cat /proc/zoneinfo cat /proc/meminfo [img-htaZj4ZA-1598499510613_media_39176a76208129a24056fa3f9bf23e04.jpg]: /images/20221123/89f103a343454cbbb8e19916d2f16d93.png [img-7HypcM2V-1598499510616_media_c0e4305d1d352443eb995b58eaf1e6b1.png]: /images/20221123/8055cc14dd804b19a6908340953e55f6.png [img-Fn0VqW9K-1598499510617_media_13ccc825d7e11b6e9345534002a6bf25.png]: /images/20221123/1967b81ab6d14d25a335fb8317d719c1.png [img-XrGeAQWP-1598499510619_media_200b79c79bbed7cc3bf79b82455a09c5.png]: /images/20221123/8e91247bcb1e47ce85b70ce77f6ce405.png [img-KnPLug2c-1598499510620_media_fbe52107869af6ec71998a87b12c39c2.png]: /images/20221123/43ba99e245b74d4dbec063ea86df5879.png [img-9BwwyJtZ-1598499510623_media_1d4cbcb84b83d8eb509049e88dfcda9f.png]: /images/20221123/ee491c01ebcf4d148327b9162128d2ca.png [img-aAZ9dkmy-1598499510624_media_b7e5bf2c1ad0ec776d99dfc99c90528d.png]: /images/20221123/2a01afde3b0a4fd18d3f9b03547d1fce.png [img-0NvPPmfQ-1598499510625_media_6073a13855c3d6c6f0334b953cd7f285.png]: /images/20221123/9139b19eed1b4182a82efc7014faeaa4.png [img-gPyKvrtv-1598499510627_media_5280f46620090ef6c3fa837ef5fbdfbe.png]: /images/20221123/b2f1adbc49b443be80954a3fdba9b6d8.png [img-7SXvN81O-1598499510628_media_552b45603d10618e2d7b0809e91253b3.png]: /images/20221123/da3ef6bc94a442689f446336b5c4c01d.png [img-LlsupTTy-1598499510628_media_5835a1555e4cb021132a1d4826cc318c.png]: /images/20221123/b5a94fc3eb3c4ee79404db93ebd0a4db.png [img-2mmpCFRL-1598499510629_media_988c1868230625fb4282deb0ff7e70c7.png]: /images/20221123/e622ef3ff3fc4c699ec1f7c5453208a5.png [img-oGbvhuSh-1598499510630_media_64ac61c220baae25eb3ee449ad3bbc89.png]: /images/20221123/278b3fd13c6c45be8b1da1d53e9d12d2.png [img-gQaQFVYl-1598499510631_media_40574a9d8e29e2f10c507ed96a5c1b4e.png]: /images/20221123/5f5f7d8656494024802062d84a0e0ed3.png [img-UKodxfIp-1598500052901_media_8323ab1eb838a435ddc6f82f731969ed.png]: /images/20221123/87e9044631054e8fb71b4164a7bbb0b8.png [img-uYOsWPOa-1598500052903_media_06e725b77df25e31fdb09166e84dd4e1.png]: /images/20221123/4b30df928d7e4eef87fb97396fde454d.png [img-aRxm0vzE-1598500052905_media_79984ebb28cbf21cd21690b20aa13ddd.png]: /images/20221123/a27ddbd4a35245329a5b782f344acc0c.png [img-zj9u8ip1-1598500174678_media_66e0b0b993fdacac3ac33583aec70b62.png]: /images/20221123/9d71f68d1cfe42b6a4c6e59f4d84d92b.png
相关 内存泄漏大揭秘:Java代码如何隐性消耗内存? 内存泄漏在编程中是一个严重的问题,特别是在使用像Java这样具有垃圾回收机制的语言。内存泄漏并不是代码直接写出来的,而是通过一系列的逻辑和程序行为慢慢消耗掉可用内存。 以下是 我不是女神ヾ/ 2024年09月10日 05:45/ 0 赞/ 23 阅读
相关 内存溢出和内存泄漏 1 如何理解内存溢出和内存泄漏 1.2 内存泄漏 所谓的内存泄漏就是堆空间的Java对象不再使用了,但是还有其他引用指向这个对象,导致这个对象不能被垃圾回收,一直占 女爷i/ 2024年03月22日 21:05/ 0 赞/ 68 阅读
相关 303-Linux虚拟内存和内核内存分配 Linux虚拟内存 虚拟内存寻址 Linux使用三级页表结构,由下面几种类型的表组成(每个表的大小都是一页): 1、页目录:一个活动进程有一个页目录,页目录为一页 约定不等于承诺〃/ 2023年01月18日 09:10/ 0 赞/ 291 阅读
相关 Linux内核之内存4: 内存与I/O的交换 1. page cache ![!\[\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cp30sAtT-1598500337083)(me 野性酷女/ 2022年12月01日 14:05/ 0 赞/ 104 阅读
相关 Linux内核之内存3: 进程的内存消耗和内存泄漏 1.进程的VMA (1)进程地址空间 在Linux系统中,每个进程都有自己的虚拟内存空间0~3G; 内核空间只有一个3G~4G; ![\[外链图片转存失败,源站 布满荆棘的人生/ 2022年12月01日 14:04/ 0 赞/ 338 阅读
相关 linux内核虚拟内存和物理内存的映射 内存访问分为两种体系结构:一致性内存访问(UMA)和非一致性内存访问(NUMA)。NUMA指CPU对不同内存单元的访问时间可能不一样,因而这些物理内存被划分为几个节点,每个节点 谁践踏了优雅/ 2022年05月15日 04:21/ 0 赞/ 452 阅读
相关 内存泄漏和内存溢出 内存泄漏和内存溢出 Java中的内存管理 1. 所有的局部变量在栈分配 1. 每个方法一个栈帧, 2. 方法中的变量在栈帧中分配 曾经终败给现在/ 2022年03月14日 10:16/ 0 赞/ 336 阅读
相关 Linux查看最消耗内存,CPU资源的进程 1. 查看消耗CPU资源最多的前10个进程 [root@localhost ~] ps auxw | head -1;ps auxw |sort -rn -k3 |h 清疚/ 2022年02月24日 04:26/ 0 赞/ 232 阅读
相关 内存泄漏和内存溢出 (1)内存泄漏和内存溢出 内存泄漏:分配出去的内存无法回收(不再使用的对象或者变量仍占内存空间),在Java中内存泄漏就是存在一些被分配的对象(可达的,却是无用的)无法被gc Love The Way You Lie/ 2021年06月24日 16:00/ 0 赞/ 693 阅读
还没有评论,来说两句吧...