Linux C内存泄露分析

31 阅读1分钟

简介

对于服务程序而言,一个头疼且致命的场景就是存在内存泄露,在系统长期运行后,可能是一个月,可能是一年,也可能是几年,剩余内存逐步减少,到最后触发oom导致服务被终止,从而无法正常在对外提供服务。

linux可以使用 top -m 查看服务程序内存使用情况,需要了解以下参数含义:

VSZ(Virtual Memory Size)

  • 是Linux系统中用于描述进程占用的虚拟内存大小的一个指标。它表示的是一个进程在虚拟内存中分配了多少空间,包括了进程使用的所有代码、数据和堆栈。

RSS (Resident Set Size)

  • 是表示进程在物理内存中实际占用的大小。与VSZ不同,RSS不包括保存在硬盘上的虚拟内存。

示例

场景一

  • 每秒malloc()分配1M,然后memset设置值。
  • VSZ、VSZRW、RSS、DIRTY都每秒增加1M

源代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main()
{
        int len=1000*1000;
        int i;
        char *p;

        for (i=0; i<2000; i++) {
                p =  malloc(len);
                memset(p, i, len);
                sleep(1);
        }
}

内存状态 image.png

场景二

  • 每秒malloc()分配1M,但不memset设置值
  • VSZ、VSZRW都每秒增加1M,而RSS、DIRTY基本保持不变

源代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main()
{
        int len=1000*1000;
        int i;
        char *p;

        for (i=0; i<2000; i++) {
                p =  malloc(len);
                sleep(1);
        }
}

内存状态 image.png

总结

  • 编码过程中需要特别注意malloc,保证正常free。
  • 可以通过静态代码检查工具扫描,查找到部分遗漏释放的场景。
  • 线上通过top、pmap、free、ps等查看内存大小,监控是否存在内存泄露。