加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_丽江站长网 (http://www.0888zz.com/)- 科技、建站、数据工具、云上网络、机器学习!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

如何在Linux操作系统下检测内存泄漏

发布时间:2016-05-30 05:29:06 所属栏目:Linux 来源:网络整理
导读:1.开发背景: 在 Windows 下使用 VC 编程时,我们通常需要 DEBUG 模式下运行程序,而后调试器将在退出程序时,打印出程序运行过程中在堆上分配而没有释放的内

不错,我们可以在内存检测子系统中的全局对象(appMemory)的析构函数中完成对消息队列的删除,但是如果被检测进程非正常退出(CTRL +C,段错误崩溃等),消息队列可就没人管了。那么我们可以不可以在全局对象(appMemory)的构造函数中使用 signal 系统调用注册 SIGINT,SIGSEGV 等系统信号处理函数,并在处理函数中删除消息队列呢?还是不行,因为被检测进程完全有可能注册自己的对应的信号处理函数,这样就会替换我们的信号处理函数。最终我们采取的方法是利用 fork 产生一个孤儿进程,并利用这个进程监视被检测进程的生存状况,如果被检测进程已经退出(无论正常退出还是异常退出),则试图删除被检测进程所创建的消息队列。下面简述其实现原理:

在全局对象(appMemory)构造函数中,创建消息队列成功以后,我们调用 fork 创建一个子进程,而后该子进程再次调用 fork 创建孙子进程,并退出,从而使孙子进程变为一个"孤儿"进程(之所以使用孤儿进程是因为我们需要切断被检测进程与我们创建的进程之间的信号联系)。孙子进程利用父进程(被检测进程)的全局对象(appMemory)得到其 PID 和刚刚创建的消息队列的标识,并传递给调用 exec 函数产生的一个新的程序映象--MemCleaner。

MemCleaner 程序仅仅调用 kill(pid, 0);函数来查看被检测进程的生存状态,如果被检测进程不存在了(正常或者异常退出),则 kill 函数返回非 0 值,此时我们就动手清除可能存在的消息队列。

6.实现上的问题:嵌套delete

在"错误方式删除带来的问题"一节中,我们对 delete operator 动了个小手术--增加了两个全局变量(DELETE_FILE,DELETE_LINE)用于记录本次 delete 操作所在的文件名和行号,并且为了同步对全局变量(DELETE_FILE,DELETE_LINE)的访问,增加了一个全局的互斥锁。在一开始,我们使用的是 pthread_mutex_t,但是在测试中,我们发现 pthread_mutex_t 在本应用环境中的局限性。

例如如下代码:

class B {…};
class A {
public:
A() {m_pB = NULL};
A(B* pb) {m_pB = pb;};
~A()
{
if (m_pB != NULL)
行号1delete m_pB;//这句最要命
};
private:
class B* m_pB;
……
}
int main()
{
A* pA = new A(new B);
……
行号2delete pA;
}

(编辑:应用网_丽江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读