内存泄漏指标分析

背景

之前判断判断程序内存有没有泄漏,是使用top命令观察RES的值是否在不断增长。这两天在排查内存泄漏问题时在网上看到两篇文章,按照这两篇文章的意思,判断一个程序的内存有没有泄漏是通过VIRT
来判断的。本文档意在搞清楚判断一个程序是否出现内存泄漏的指标。

上文提到的文章网址

https://blog.csdn.net/leacock1991/article/details/111086130

https://blog.csdn.net/jersonborn521/article/details/123043740

前置知识

VIRT

1.进程“需要的”虚拟内存大小,包括进程使用的库、代码、数据,以及malloc、new分配的堆空间和分配的栈空间等;
2、假如进程新申请10MB的内存,但实际只使用了1MB,那么它会增长10MB,而不是实际的1MB使用量。
3、VIRT=SWAP+RES

RES

1、进程当前使用的内存大小,包括使用中的malloc、new分配的堆空间和分配的栈空间,但不包括swap out量;
2、包含其他进程的共享;
3、如果申请10MB的内存,实际使用1MB,它只增长1MB;
4、RES=CODE+DATA 

SHR

1、除了自身进程的共享内存,也包括其他进程的共享内存;
2、虽然进程只使用了几个共享库的函数,但它包含了整个共享库的大小;
3、计算某个进程所占的物理内存大小公式:RES – SHR;
4、swap out后,它将会降下来。

内存泄漏

内存发生泄漏是因为我们的程序通过大量的malloc或者new操作来申请内存的后,没有及时或者根本没有释放内存导致的,

推断

根据以上知识可推断出

  • 1.RES是进程实际使用的内存大小,RES<=进程开辟空间的大小,即RES<=VIRT。有可能进程开辟10MB的空间,但实际只使用了1MB,那么RES的值为1MB,运行一段时间之后进程需要空间增长到2MB,那么RES的值为2MB,注意这时并没有调用mallo或者new来开辟空间;
  • 2.进程在运行过程中没有开辟空间,那么VIRT不会增大;
  • 3.进程在运行过程中开辟了空间,那么VIRT就会增大;
  • 4.进程在运行过程中没有开辟空间,但随着程序的运行需要使用的空间增大了,导致RES增大,当RES增大到一定值时会导致程序崩溃;

实验 – 推断证明

实验1

代码如下:

int main()
{
    int len = 1024 * 1024 * 100;
    int i = 0;
    char *p[10] = {NULL};

    sleep(5);

    printf("malloc mem\n");
    for(int i = 0 ; i < 10; i++) //每过10s,开辟100MB的使用空间,共开1GB空间
    {
        printf("malloc-%d\n", i);
        p[i] =  (char*)malloc(len);
        sleep(10);
    }

    printf("use mem\n");
    for(int i = 0 ; i < 10; i++) //每过10s,增加100MB的使用空间
    {
        printf("use-%d\n",i);
        memset(p[i], 1, len);
        sleep(10);
    }

    printf("free mem\n");
    for(int i = 0 ; i < 10; i++) //每过10s,释放100MB的使用空间
    {
        printf("free-%d\n",i);
        free(p[i]);
        sleep(10);
    }

    return 0;
}

内存使用情况如下图:
在这里插入图片描述

实验代码分为3个阶段

  • 开辟内存环节–malloc mem

    代码运行开始阶段,开辟了1GB的内存,此时使用top命令并没有显示出程序使用内存的情况,可能是因为没有占用实际内存。

  • 使用内存环节–use mem

    进入use mem之后,每过10s,增加100MB的使用空间,此时top命令显示出程序的内存使用情况,可以看到VIRT没有增加,随着使用空间的增大,RES出现了增大。

  • 释放内存环节–free mem

    释放内存,VIRT和RES都在减小

实验2

代码

int main()
{
    int len = 1024 * 1024 * 1000;
    int i = 0;
    char *p[10] = {NULL};

    sleep(5);

    printf("malloc mem\n");
    for(int i = 0 ; i < 10; i++) //开10GB空间
    {
        printf("malloc-%d\n", i);
        p[i] =  (char*)malloc(len);
        sleep(10);
    }


    printf("use mem\n");
    for(int i = 0 ; i < 10; i++) //每过10s,增加1GB的使用空间
    {
        printf("use-%d\n",i);
        memset(p[i], 1, len);
        sleep(10);
    }


    printf("free mem\n");
    for(int i = 0 ; i < 10; i++) //每过10s,释放1GB的使用空间
    {
        printf("free-%d\n",i);
        free(p[i]);
        sleep(10);
    }


    return 0;
}

内存使用情况如下图:
在这里插入图片描述

实验代码分为3个阶段

  • 开辟内存环节–malloc mem

    代码运行开始阶段,开辟了10GB的内存,此时使用top命令并没有显示出程序使用内存的情况,可能是因为没有占用实际内存。

  • 使用内存环节–use mem

    进入use mem之后,每过10s,增加1GB的使用空间,此时top命令显示出程序的内存使用情况,可以看到VIRT没有增加,随着使用空间的增大,RES出现了增大, 当RES增大到7.8g之后被系统kill。

  • 释放内存环节–free mem

结论

  • 程序在运行过程中,VIRT一直在增大,说明可能存在内存泄漏;
  • 程序在运行过程中,VIRT没有增大,说明程序没有开辟新的空间,只要VIRT小于系统限定的内存,程序就是安全的,它不会由于内存超过系统限定的内存而被系统Kill;
  • 程序在运行过程中RES增大,当VIRT小于系统限定的内存时,程序是安全的;
  • 程序在运行过程中RES增大,当VIRT大于系统限定的内存时,程序是不安全的,,它有可能因为内存超过系统限定的内存而被系统Kill,也有可能被swap out;

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用JProfiler来查看内存泄漏,可以按照以下步骤进行操作: 1. 打开JProfiler,创建一个新的会话。 2. 在会话中,找到内存视图。内存视图提供了动态更新的内存使用情况以及分配点的信息视图。 3. 在内存视图中,你可以查看当前存在的对象和作为垃圾回收的对象。通过观察对象的引用关系和内存占用情况,可以识别潜在的内存泄漏问题。 4. JProfiler还提供了一些分析工具,例如Heap Walker和Allocation Call Tree,可以帮助你更深入地分析内存泄漏的原因和定位问题的根源。 5. 如果你已经确定某个对象存在内存泄漏,可以使用JProfiler的快照功能,记录下当前内存的状态,以供后续分析和比较。 总结起来,使用JProfiler来查看内存泄漏,你可以通过内存视图和分析工具来观察对象的引用关系和内存使用情况,以找出潜在的问题并进行深入分析。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [jprofiler 查看程序内存泄露](https://blog.csdn.net/qilixiang012/article/details/43270311)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [Java剖析工具JProfiler查找内存泄漏](https://blog.csdn.net/stefan520/article/details/8961627)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值