检查是否内存泄漏的方法

目录

前言一个简单的内存泄漏检查内存泄露的方法方法内存泄漏时,内存的消耗没有内存泄露时的内存消耗

前言

这两天抽空把之前买的这门课给看了看,课程很好,有兴趣的也可以看一看:

18909c1ed5e74c5f6cae47e129c06be7.png

具体的课程总结过几天写一写,这篇推送就说一下从这课上学到的一个技巧吧:一个检查内存泄露的方法。

这个方法呢,我觉得应该是用在开发阶段的,就是每当我们写好一个模块或者一个功能时,就检查一下,确保无误在接着往下做。

网上也有一些检查内存泄漏的工具,一搜一大堆资料就出来了,我就不介绍了。

先看一个简单的内存泄漏

#include <iostream>

using namespace std;

void testFunc()
{
    char* str = new char[1024];
    /// Some options

    std::cout << "testFunc end" << std::endl;
}

int main()
{
    /// Some options

    testFunc();

    /// Some options

    return 0;
}

在 testFunc 函数中 我在堆中开辟了 1024 字节的内存,但是程序结束时我并没有释放它,这样就堆中的这个 1024字节的内存 就一直被占用着,所以就造成了内存泄漏。

这种简单的内存泄露问题,学过C++的一眼就能看出来,为了避免这样的问题发生,我们一般用智能指针,或者记得 delete / delete[],像下面这样:

#include <iostream>
#include <memory>

using namespace std;

void testFunc()
{
    char* str = new char[1024];
    /// Some options

    delete[] str;

    std::cout << "testFunc end" << std::endl;
}

但是,像下面的这样的代码呢,不了解这个库的话可能看不出来有内存泄漏:

96549f9ad4a8362bbf338e6888505204.png

其实也不复杂,这些都是 <Python.h> 里面的东西,用C++给Python做拓展库 或者 C++调用Python脚本时会用。

Python中的垃圾回收机制主要是看变量的引用计数,如果引用计数为0时再销毁,我们在做Python的拓展库时,在C++这边是需要我们手动地去增减引用计数的。所以就得控制好这个引用计数,不然一不小心可能就造成了内存泄露了。

由于开发过程中可能会用到一些自己不太熟悉的库,就比如上面的 我就可能忘写上红框里面的代码了,那么就会造成内存泄露了。

上面这两个例子仅仅是调用了一次,并不会消耗太多的内存。但是,在实际的生产中,我们程序可能会是一直在运行的,那么就可能会一直在泄露内存。积少成多,最后宕掉。

为了避免造成内存泄漏的发生,我们在写好一个函数或者一个功能时就及时地对它进行检测,看看是否会造成内存泄露!

检查内存泄露的方法

方法

我们没必要对着代码一行一行地检查,我们只需做一个死循环,不断重复地执行所测试的函数模块然后打开任务管理器,看内存的增长情况,如果内存在不断地增加那么可能就是内存泄露了。如果有内存泄漏的话,死循环会造成内存快速增长,所以可以判断出是否发生内存泄漏。

如果你用的是VS的话,里面的诊断工具里面有一个进程内存可以看到内存的增长情况,如下。

fc0475b674826a7126894d238378be97.jpeg

我平时都用的CLion进行开发,所以就通过看任务管理器了。

如果我们确认了这个模块函数会发生内存泄漏,那么再去一行一行看代码吧。所以平时还是写一点然后就去测试一下!

下面我就拿 VS2017 测试一下

内存泄漏时,观察内存的消耗

代码:

#include "stdafx.h"
#include <iostream>
#include <memory>

using namespace std;

void testFunc()
{
    char* str = new char[1024];
    /// Some options

    std::cout << "testFunc end" << std::endl;
}

int main()
{
    /// Some options
    while (1)
        testFunc();

    /// Some options

    return 0;
}

下面是几个时间点下的截图(看右侧),可以看到内存的迅速增长:

3ab526b415cb95474ccf7c3577358930.png


3c2f8babdc620360879e2cbbc05c61ce.png


2d80e9b5326ee102943c5622ebf7f1bf.png

没有内存泄露时的内存消耗

代码就多了一个 delete [] str。

b5d8ed5ca07ef57c1649260707445ea4.png

一分钟后 内存消耗 还是 937 KB

8c93fffec786b5bc44212e461906bf1b.png

对比可以看到,用死循环来判断内存是否泄露还是一个比较可靠的方法的,如果有泄露,一会内存就消耗没了。

上面会泄露内存的 一会就消耗了几个G,而下面的那个不泄露内存的一直也就几百KB。

b548344562ce619f0da79bd6b326dc81.png

baf5498e377eff88309ddc9ed7e1dffb.jpeg

0f2a023eab24de7263f11ae3d648722f.png

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值