天天看点

内存泄露查看方法

定义:

内存被占用,使用完成后没有释放

产生原因:

使用malloc或者new操作之后没有相应的free或者delete

危害:

内存大量损耗后导致程序越来越慢

发现内存泄露

  • ps-aux

    查看各个进程的内存占用率,如果某个进程占用的内存在一直上升,很有可能发生了内存泄露

  • 其他命令free

     查看整个系统的内存使用情况

方法

定义出一个关于new的类,然后将new运算符重载,将每一个定义的new的位置和所在文件保存到数组中,当这个new没有被删除时,则会显示出来所在的位置

代码:

main.cpp

#include"DebugNew.h"

int main()
{
	int *p = new int;

	return 0;
}



           

DebugNew.h

#ifndef DEBUG_NEW_H_
#define DEBUG_NEW_H_
#include"TreacNew.h"

//全局对象
//记录 new 记录
//     delete 删除记录一次

#define new new(__FILE__,__LINE__)

#endif   
           

TreacNew.h

#include<map>

void *operator new(size_t size, const char *file, long line);
void operator delete(void *p);

class TreacNew
{
	class TracerNewInfo
	{
	public:
		TracerNewInfo(const char *file = nullptr, long line = 0);
		const char *File() const;
		long Line() const;
	private:
		const char *file_;
		long line_;
	};
public:
	static bool Ready;
	TreacNew();
	~TreacNew();
	void Add(void *p, const char *file, long line);
	void Remove(void *p);
	void Dump();
private:
	std::map<void *, TracerNewInfo> treaer_infos_;
};

extern TreacNew NewTrace;
           

TreacNew.cpp

#include "TreacNew.h"
#include<cstdlib>
#include<iostream>

TreacNew NewTrace;
bool TreacNew::Ready = false;

TreacNew::TreacNew()
{
	TreacNew::Ready = true;
}


TreacNew::~TreacNew()
{
	TreacNew::Ready = false;
	Dump();
}

void *operator new(size_t size, const char *file, long line)
{
	void *p = malloc(size);
	//开始记录
	NewTrace.Add(p, file, line);
	return p;
}

void operator delete(void *p)
{
	if (TreacNew::Ready)
	{
		NewTrace.Remove(p);
	}
	free(p);
}

TreacNew::TracerNewInfo::TracerNewInfo(const char *file, long line) :file_(file), line_(line)
{

}

const char* TreacNew::TracerNewInfo::File() const
{
	return file_;
}

long TreacNew::TracerNewInfo::Line() const
{
	return line_;
}

void TreacNew::Add(void *p, const char *file, long line)
{
	treaer_infos_[p] = TracerNewInfo(file, line);
}

void TreacNew::Remove(void *p)
{
	auto it = treaer_infos_.find(p);
	if (it != treaer_infos_.end())
	{
		treaer_infos_.erase(it);
	}
}

void TreacNew::Dump()
{
	for (auto tracer_info : treaer_infos_)
	{
		std::cout << "0x" << tracer_info.first << "\t" << tracer_info.second.File() << "\tIn Line" << tracer_info.second.Line() << std::endl;
	}
}