内存泄漏,内存黑洞问题定位

1. free查看内存概况

[root@VM_0_17_centos ~]# freetotal        used        free      shared  buff/cache   available
Mem:        1883844      376664       76136         192     1431044     1311252
Swap:       1048572       30540     1018032

通过对free查看,我们对内存的整体使用有个初步了解,并快速是否存在内存泄漏可能。

1.1 used占用正常,free很低,但是buff/cache和available挺高

这种情况不是内存泄漏,而是系统将可用内存cache起来了。在需要的时候可以释放出来使用。

如需手动释放,可执行 echo x > /proc/sys/vm/drop_caches 将缓存释放出来。(x=1,2,3)
**是否可以控制:**如命令有效果,观察内存不再升高,为控制住。表面不是内存泄露,只是cache较大。

1.2 used占用较高

这种情况存在内存泄漏可能,需要继续向下分析。

2. /tmp目录查看

/tmp目录是占用内存空间的,有时候日志或者其他临时文件过大,导致内存占用过多。

[root@VM_0_17_centos ~]# du -sh /tmp/*
0       /tmp/systemd-private-0bd2eb2d32be4029bb93736c12f9cfc6-httpd.service-93VBb6
0       /tmp/systemd-private-0bd2eb2d32be4029bb93736c12f9cfc6-ntpd.service-s017JD
0       /tmp/systemd-private-5245a0f476c64b80895d3fe3e5c5e9e6-httpd.service-Hp8PSy
0       /tmp/systemd-private-5245a0f476c64b80895d3fe3e5c5e9e6-ntpd.service-yQr1bn
0       /tmp/UNIX.domain

**是否可以控制:**需要确认是否可删除。

3. ps 查看进程内存占用

[root@VM_0_17_centos ~]# ps aux --sort -rss | head -n 10
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root     11625  0.0  0.0  97292  1732 ?        Sl   14:48   0:00 /usr/local/qcloud/stargate/sgagent -d
root     11636  0.0  0.1 102348  2220 ?        Ssl  14:48   0:00 /usr/local/qcloud/YunJing/YDLive/YDLive
root     11640  0.0  0.4 155208  7572 ?        S    14:48   0:00 barad_agent
root     11645  0.0  0.4 158112  9192 ?        S    14:48   0:04 barad_agent
root     11646  0.3  0.5 609092 11260 ?        Sl   14:48   0:19 barad_agent

ps命令可以帮助我们定位分析应用进程内存泄漏。
观察RSS列,如果有进程RSS占用偏高,则存在内存泄漏可能。
需分析该程序源码是否存在泄漏可能。

4. /proc/meminfo查看内存信息

[root@VM_0_17_centos ~]# cat /proc/meminfo
MemTotal:        1883844 kB
MemFree:          970208 kB
MemAvailable:    1321960 kB
Buffers:           51864 kB
Cached:           405336 kB
SwapCached:            0 kB
Active:           272120 kB
Inactive:         321892 kB
Active(anon):     137008 kB
Inactive(anon):      156 kB
Active(file):     135112 kB
Inactive(file):   321736 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       1048572 kB
SwapFree:        1048572 kB
Dirty:               288 kB
Writeback:             0 kB
AnonPages:        136824 kB
Mapped:            42852 kB
Shmem:               356 kB
Slab:              67860 kB
SReclaimable:      52156 kB
SUnreclaim:        15704 kB
KernelStack:        1824 kB
PageTables:         3736 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     1990492 kB
Committed_AS:     412576 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      223536 kB
VmallocChunk:   34359484404 kB
HardwareCorrupted:     0 kB
AnonHugePages:     83968 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       63480 kB
DirectMap2M:     2033664 kB

meminfo中对内存的使用进行了详细的统计,我们主要关注Slab和VmllocUsed。

4.1 观察Slab相关是否占用偏高

Slab = SReclaimable + SUnreclaim
如果内存占用偏高,且SReclaimable偏高,则表示可用内存缓存在slab系统内,需要时可回收。
如果内存占用偏高,且SUnreclaim偏高,则表示可能存在内存泄漏。需要进一步观察slabinfo

[root@VM_0_17_centos ~]# cat /proc/slabinfo
slabinfo - version: 2.1
# name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
mempool_flow_buf       0      0   1088   15    4 : tunables    0    0    0 : slabdata      0      0      0
mempool_rule_buf       6      6   5184    6    8 : tunables    0    0    0 : slabdata      1      1      0
mempool_rule_block      4      4 106560    1   32 : tunables    0    0    0 : slabdata      4      4      0
lw_domain           1728   1728    320   12    1 : tunables    0    0    0 : slabdata    144    144      0
isofs_inode_cache     12     12    640   12    2 : tunables    0    0    0 : slabdata      1      1      0
ext4_groupinfo_4k    420    420    136   30    1 : tunables    0    0    0 : slabdata     14     14      0
ext4_inode_cache   27060  27060   1032   15    4 : tunables    0    0    0 : slabdata   1804   1804      0

通过查看slabinfo,可以观察到具体是哪些slab的占用偏高,帮助进一步缩小问题范围。

4.2 观察VmallocUsed相关占用是否偏高

如果占用较高,表示vmalloc分配可能存在泄漏。需要进一步分析vmallocinfo

[root@VM_0_17_centos ~]# cat /proc/vmallocinfo
0xffffc90000000000-0xffffc90000201000 2101248 alloc_large_system_hash+0x171/0x239 pages=512 vmalloc N0=512
0xffffc90000201000-0xffffc90000302000 1052672 alloc_large_system_hash+0x171/0x239 pages=256 vmalloc N0=256
0xffffc90000302000-0xffffc90000304000    8192 acpi_os_map_memory+0xea/0x142 phys=fed00000 ioremap
0xffffc90000304000-0xffffc90000307000   12288 acpi_os_map_memory+0xea/0x142 phys=7fffe000 ioremap
0xffffc90000307000-0xffffc90000328000  135168 alloc_large_system_hash+0x171/0x239 pages=32 vmalloc N0=32
0xffffc90000328000-0xffffc90000369000  266240 alloc_large_system_hash+0x171/0x239 pages=64 vmalloc N0=64
0xffffc90000369000-0xffffc90000372000   36864 alloc_large_system_hash+0x171/0x239 pages=8 vmalloc N0=8
0xffffc90000372000-0xffffc9000037b000   36864 alloc_large_system_hash+0x171/0x239 pages=8 vmalloc N0=8
0xffffc9000037b000-0xffffc90000380000   20480 alloc_large_system_hash+0x171/0x239 pages=4 vmalloc N0=4
0xffffc90000380000-0xffffc90000382000    8192 pci_enable_msix+0x2f1/0x430 phys=febf1000 ioremap
0xffffc90000382000-0xffffc90000384000    8192 pci_enable_msix+0x2f1/0x430 phys=febf3000 ioremap
0xffffc90000385000-0xffffc900003a6000  135168 raw_init+0x41/0x141 pages=32 vmalloc N0=32
0xffffc900003a6000-0xffffc900003a8000    8192 swap_cgroup_swapon+0x48/0x160 pages=1 vmalloc N0=1
0xffffc900003a8000-0xffffc900003ab000   12288 module_alloc_update_bounds+0x14/0x70 pages=2 vmalloc N0=2
0xffffc900003ac000-0xffffc900003ae000    8192 cirrus_device_init+0x8a/0x150 [cirrus] phys=febf0000 ioremap
0xffffc900003b0000-0xffffc900003b2000    8192 LW_VmemZeroAlloc+0x4e/0xc0 [lwconn] pages=1 vmalloc N0=1
0xffffc900003b2000-0xffffc900003b4000    8192 LW_VmemAlloc+0x4e/0xc0 [lwconn] pages=1 vmalloc N0=1

通过查看vmallocinfo,可以更详细的定位到是那个操作申请的内存过多,导致内存占用高,帮助我们定位问题原因。

5. 内存黑洞

linux系统中有部分内存是通过直接操作page申请的,/proc/meminfo无法统计到,这部分内存就像黑洞一样。

如果前面步骤还不能定位到问题,我们可以通过下面公式计算一下黑洞内存的大小:

黑洞内存 = MemTotal - MemFree - Active - Inactive - Slab - KernelStack - PageTables - VmallocUsed

如果计算出来黑洞内存占用过大,基本确认是黑洞内存占用导致。

目前看来导致内存黑洞主要有以下几个方面:

5.1 系统socket 收发队列积压过多数据包导致内存不足

系统的socket收发队列积压,我们可以通过netstat命令查看

[root@VM_0_17_centos ~]# netstat -noap
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name     Timer
...//省略部分
udp        0      0 0.0.0.0:67              0.0.0.0:*                           3240/dnsmasq         off (0.00/0/0)
udp        0      0 61.170.203.43:123       0.0.0.0:*                           3130/ntpd            off (0.00/0/0)
udp        0      0 169.254.200.1:123       0.0.0.0:*                           3130/ntpd            off (0.00/0/0)
udp        0      0 192.168.1.1:123         0.0.0.0:*                           3130/ntpd            off (0.00/0/0)
udp        0      0 127.0.0.1:123           0.0.0.0:*                           3130/ntpd            off (0.00/0/0)
udp        0      0 0.0.0.0:123             0.0.0.0:*                           3130/ntpd            off (0.00/0/0)
udp6       0      0 fe80::84cf:68ff:fe8:123 :::*                                3130/ntpd            off (0.00/0/0)
udp6       0      0 ::1:123                 :::*                                3130/ntpd            off (0.00/0/0)
udp6       0      0 :::123                  :::*                                3130/ntpd            off (0.00/0/0)
raw6  76755840      0 :::58                   :::*                    7           3218/zebra           off (0.00/0/0)
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node   PID/Program name     Path
unix  2      [ ACC ]     STREAM     LISTENING     27149    3225/bgpd            /var/run/quagga/bgpd.vty
unix  2      [ ]         DGRAM                    9249     1/systemd            /run/systemd/notify
unix  2      [ ]         DGRAM                    25891    2871/rsyslogd        /run/systemd/journal/syslog
unix  2      [ ]         DGRAM                    9251     1/systemd            /run/systemd/cgroups-agent
unix  2      [ ACC ]     STREAM     LISTENING     25447    3229/ospfd           /var/run/quagga/ospfd.vty
...//省略部分

上面这个就是3218/zebra进程收报队列积压了76755840导致内存耗尽。systemctl stop zebra后问题解决。
**是否可以控制:**一般可控,手动停止或重启有问题的服务。

5.2 pf_packet socket收发队列积压过多数据包导致内存不足

pf_packet socket收发队列积压,我们可以通过ss命令查看

[root@cpe ~]# ss -pf link
Netid  Recv-Q Send-Q                                                                                          Local Address:Port                                                                                                           Peer Address:Port
p_raw  10095232 0                                                                                                    ppp_disc:eth1                                                                                                                       *                      users:(("pppd",pid=17865,fd=10))

上面这个就是17865/pppd 进程收报队列积压了10095232 导致内存消耗过多。重启pppd服务后,占用内存可以释放掉。

5.3 vmware虚拟机balloon技术导致内存占用过高

关于虚拟化balloon技术,简单来说就是在虚拟机中存在一个气球(balloon),气球中的内存是给宿主机使用的,虚拟机不能使用。
当宿主机需要内存时,可以请求虚拟机释放内存到气球中,也就是气球的充气膨胀。这样虚拟机的可用内存减少了,宿主机实际可用内存增大了。
反过来,虚拟机需要内存时,可以让气球放气缩小,也就是宿主机释放内存,让虚拟机有更多内存可使用。
balloon驱动就是直接alloc_pages操作内存,所以meminfo无法追踪到。

如果虚拟机上通过meminfo发现内存黑洞,有可能就是balloon导致。我们可以通过以下方法验证。

-bash-4.2# free -h  //查看内存占用,有大概1.2G隐形内存占用total        used        free      shared  buff/cache   available
Mem:           1.8G        1.2G         77M         31M        488M        369M
Swap:          1.6G         69M        1.5G
-bash-4.2# rmmod vmw_balloon    //卸载balloon
-bash-4.2# free -h      //查看内存占用,此时被占用的1.2G内存释放出来了total        used        free      shared  buff/cache   available
Mem:           1.8G         78M        1.2G         31M        488M        1.5G
Swap:          1.6G         69M        1.5G

内存泄漏,内存黑洞问题定位相关推荐

  1. 内存泄漏的检测、定位和解决经验总结

    内存泄漏的检测.定位和解决经验总结 温辉敏(wenhm@sina.com) 2006 年 05 月 [摘要] 结合局端MCU项目中CSS.NMS模块内存泄漏检测.修正的过程,简要介绍了内存泄漏检测的工 ...

  2. Android App解决卡顿慢之内存抖动及内存泄漏(发现和定位)

    内存抖动是指在短时间内有大量的对象被创建或者被回收的现象,内存抖动出现原因主要是频繁(很重要)在循环里创建对象(导致大量对象在短时间内被创建,由于新对象是要占用内存空间的而且是频繁,如果一次或者两次在 ...

  3. 内存泄漏 内存溢出 踩内存 malloc底层实现原理

    本文主要对内存泄漏.内存溢出.内存踩踏[踩内存]以及malloc的底层实现原理进行了总结.话不多说,直接往下看: 参考文章: 内存泄漏与内存溢出: https://blog.csdn.net/ruir ...

  4. 内存泄漏——内存溢出区别

    内存溢出和内存泄漏的区别.产生原因以及解决方案 内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory:比如申请了一个integer,但 ...

  5. 18 | 案例篇:内存泄漏了,我该如何定位和处理?

    通过前几节对内存基础的学习,我相信你对 Linux 内存的工作原理,已经有了初步了解. 对普通进程来说,能看到的其实是内核提供的虚拟内存,这些虚拟内存还需要通过页表,由系统映射为物理 当进程通过 ma ...

  6. 利用工具定位内存泄漏问题 valgrind memwatch dmalloc

    内存泄漏定位工具 内存debug有比较多的方法,首先可以参看如下的wiki,查看大概都有哪些方式,再根据其有缺点选用,适合自己需要的方式. Memory Debuggers https://elinu ...

  7. Android内存泄漏定位、分析、解决全方案

    为什么会发生内存泄漏 内存空间使用完毕之后未回收, 会导致内存泄漏.有人会问:Java不是有垃圾自动回收机制么?不幸的是,在Java中仍存在很多容易导致内存泄漏的逻辑(logical leak).虽然 ...

  8. 1.内存优化(一)内存泄漏

    目录 内存泄漏 什么是内存泄漏 了解内存分配的几种策略 防止内存泄漏 内存泄漏的例子 如何找到项目中存在的内存泄露 确定是否存在内存泄露 哪些对象属于泄漏的(找出来) 定位内存泄露的原因所在 如何在应 ...

  9. linux踩内存内存越界,Linux如何调试内存泄漏?超牛干货奉献给你(代码全)

    内存泄漏是指由于疏忽或错误造成程序未能释放已经不再使用的内存.内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存 ...

  10. C++ 动态内存管理:c/c++的动态内存管理,new/delete,operator new/delete,placement-new, 内存泄漏

    c/c++的动态内存管理 new/delete opeartor new/delete placement-new 内存泄漏 c/c++的动态内存管理 在开始之前首先要了解c和c++的内存分布,我简单 ...

最新文章

  1. 英伟达十年力作:新一代光线追踪显卡 Quadro RTX及核心架构Turing,可支持AI运算...
  2. Ubuntu18.04.4 报错Name or service not known
  3. k8s使用glusterfs存储报错type 'features/utime'
  4. python windows服务_Python创建Windows服务
  5. 什么都不懂的学java难不难_零基础转行学java到底难不难
  6. 软件测试缺陷定义和管理
  7. 端口扩展器技术让网络交换焕然一新
  8. stata导入数据问题
  9. 微软补丁星期二修复已遭利用的 Defender 0day
  10. UEFI win7系统的安装
  11. 【安全狐】robots协议详解(robots.txt)
  12. WinSnap 截图工具绿色中文特别版
  13. “数据中台”在安防行业的应用与发展
  14. 网页中视频在线播放脚本
  15. 递归专题---[2]开根号
  16. python裁剪图片边缘模糊_用cv2模糊部分图像后的锐利边缘
  17. 2021-05-02 收心继续
  18. html 好看的数据表格,CSS制作好看的网页表格
  19. xdoj 238 数组鞍点 二维数组 循环
  20. 树木分形迭代图 matlab,基于迭代函数系统的分形植物模拟

热门文章

  1. 2019领航杯write up
  2. 【号外】百度承认资质审核存在很大问题
  3. MachineLearning 12. 机器学习之降维方法t-SNE及可视化 (Rtsne)
  4. Key 3D Rigging Terms to Get You Moving - 关于 3D Rigging 的一些术语
  5. Java 类java.security.spec.PKCS8EncodedKeySpec 实例源码
  6. 用命令窗口合并多个sql文件方法
  7. 洛谷P8707 [蓝桥杯 2020 省 AB1] 走方格 C语言/C++
  8. 调包侠系列之—调用face_recognition进行人脸识别
  9. 最新Android面试题整理,全套教学资料
  10. 自闭症是什么吗?新手家长必读