设为首页 | 加入收藏

欢迎访问湖南幸运赛车开奖直播_幸运赛车开奖视频直播_幸运赛车开奖直播

活动预告 >> 湖南幸运赛车开奖直播-怎样处理Linux内存走漏?

首要阐明下,作者自己是C/C++程序员出道。C/C++什么都好,便是内存办理让人头疼。关于这种没有Garbage Collection的言语, C 和 C++ 程序中完全由程序员自主请求和开释内存,稍不留意,就会在体系中导入内存过错。一起,内存过错往往十分严峻,一般会带来比如体系溃散,内存耗尽(OOM),逻辑反常(内存践踏)这样严峻的结果。这些结果,都是无法承受的。最要命的是内存走漏通常是无声无息的发作。存在内存过错的 C 和 C++ 程序会导致各种问题。假如它们走漏内存,则运转速度会逐步变慢,并终究中止运转;假如掩盖内存,则会逻辑反常,很简略遭到hacker的进犯。

说了这么多,内存走漏的严峻性,那究竟什么是内存走漏呢?

内存走漏一般情况下是指从堆中请求的内存没有开释。堆的概念能够在我的怎样深化了解堆和栈这篇文章中寻觅到答案。应用程序调用malloc,realloc,new函数从堆中请求一块内存,在运用结束后,需求调用free/new来开释内存。假如短少开释,就会导致内存走漏。一朝一夕,整个体系的内存将会渐渐耗尽。

那咱们该怎么及时发现内存走漏呢?下面罗列下:

  1. 代码review阶段,这个阶段的价值能够发现简略的内存走漏问题
  2. 代码静态检测东西,coverity等等。这类东西比较强壮,绝大部分的内存走漏危险都能检测出来。
  3. 运转阶段,合作体系有内存监督东西,搜集一段时间内的仓库内存信息,观测增加趋势,来确认是否有内存走漏。例如:ps,top,cat /proc/{pid}/status,cat /proc/{pid}/maps等等。
  4. 运转阶段,内存检测东西。这类东西也比较多。常用如下:




在这几款东西中,设置最简略的应该是memwatch了,和dmalloc相同,它能检测未开释的堆内存,内存被开释屡次,内存不合法拜访问题。

它之所以是简略好用,是因为他底子不需求装置,仅仅一段代码,需求include头文件memwatch.h和源代码包括memwatch.c,编译需求加上-DMEMWATCH -DMW_STDIO。例如:


gcc -DMEMWATCH -DMW_STDIO hicore.c memwatch.c -o hicore

memwatch输出文件名称为memwat湖南幸运赛车开奖直播-怎样处理Linux内存走漏?ch.log,运转期间所以内容都会输出在stdout

举个比如吧(这个比如简略的令人发指,仅仅为了阐明思路):


#include 
#include
#include
#include
int main() {
char *hello;
if ((hello = (char *) malloc(sizeof(char))) == NULL) {
perror("Cannot allocate memory.");
return -1;
}
re湖南幸运赛车开奖直播-怎样处理Linux内存走漏?turn 0;
}

编译指令:


gcc -DMEMWATCH -DMW_STDIO test.c memwatch.c -o test

memwatch.log的內容如下:


============= MEMWATCH 2.71 Copyright (C) 1992-1999 Johan Lindh =============
Started at Mon May 27 22:48:47 2019
Modes: __STDC__ 32-bit mwDWORD==(unsigned long)
mwROUNDALLOC==4 sizeof(mwData)==32 mwDataSize==32
Stopped at Mon May 27 22:48:47 2019
unfreed: <1> test.c(7), 1 bytes at 0x805108c {FE .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .}
Memory usage statistics (global):
N)umber of allocations made: 1
L)argest memory usage : 1
T)otal of all alloc湖南幸运赛车开奖直播-怎样处理Linux内存走漏?() calls: 1
U)nfreed bytes totals : 1

从文件的内容能够看出,在程序履行到test.c的第7行时,堆内存未开释,该段内存的巨细为1 byte。

Memwatch 的长处是无需特別装备,不需装置便能运用,但缺陷是它会拖慢程序的运转速度,尤其是开释内存时它会作很多查看。但它比mtrace和dmalloc多了一项功用,便是能模仿体系内存不足的情況,运湖南幸运赛车开奖直播-怎样处理Linux内存走漏?用者只需用mwLimit(long num_of_byte)函数来约束程式的heap memory巨细(以byte单位)。

具体的运用办法和运转原理能够在README中寻觅答案。

进阶1

有人会问了还有没有其他的办法来检测内存走漏呢?答案是有的。

重载new 和 delete。这也是我们编码进程中常常运用的办法。当然也能够重载malloc和free。仅仅在C言语中,没有重载的概念。暂时就叫重载吧。

测验代码:


#include
using namespace std;
//---------------------------------------------------------------
// 内存记载
//---------------------------------------------------------------
class MemInfo {
private:
void* ptr;
const char* file;
unsigned int line;
MemInfo* link;
friend class MemStack;
};
//---------------------------------------------------------------
// 内存记载栈
//---------------------------------------------------------------
class MemStack {
private:
MemInfo* head;
public:
MemStack():head(NULL) { }
~MemStack() {
MemInfo* tmp;
while(head != NULL) {
free(head->ptr); // 开释走漏的内存
tmp = head->link;
free(head);
head = tmp;
}
}
void Insert(void* ptr, const char* file, unsigned int line) {
MemInfo* node = (MemInfo*)malloc(sizeof(MemInfo));
node->ptr = ptr; node->file = file; node->line=line;
node->link = head; head = node;
}
void Delete(void* ptr) {
MemInfo* node = head;
MemInfo* pre = NULL;
while(node != NULL && node->ptr!=ptr) {
pre = node;
node = node->link;
}
if(node == NULL)
cout << "删去一个没有拓荒的内存" << endl;
else {
if(pre == NULL) // 删去的是head
head = node->link;
else
pre->link = node->link;
free(node);
}
}
void Print() {
if(head == NULL) {
cout << "内存都开释掉了" << endl;
return;
}
cout << "有内存走漏呈现" << endl;
MemInfo* node = head;
while(node != NULL) {
cout << "文件名: " << node->file << " , " << "行数: " << node->line << " , "
<< "地址: " << node->ptr << endl;
node = node->link;
}
}
};
//---------------------------------------------------------------
// 大局目标 mem_stack记载拓荒的内存
//---------------------------------------------------------------
MemStack mem_stack;
//---------------------------------------------------------------
// 重载new,new[],delete,delete[]
//---------------------------------------------------------------
void* operator new(size_t size, const char* file, unsigned int line) {
void* ptr = malloc(size);
mem_stack.Insert(ptr, file, line);
return ptr;
}
void* operator new[](size_t size, const char* file, unsigned int line) {
return operator new(size, file, line); // 不能用new
}
void operator delete(void* ptr) {
free(ptr);
mem_stack.Delete(ptr);
}
void operator delete[](void* ptr) {
operator delete(ptr);
}
//---------------------------------------------------------------
// 运用宏将带测验代码中的new和delte替换为重载的new和delete
//---------------------------------------------------------------
#define new new(__FILE__,__湖南幸运赛车开奖直播-怎样处理Linux内存走漏?LINE__)
//---------------------------------------------------------------
// 待测验代码
//-----------------------------------------------------------雨农谈股----
void bad_code() {
int *p = new int;
char *q = new char[5];
delete []q;
}
void good_code() {
int *p = new int;
char *q = new char[5];
delete p;
delete []q;
}
//---------------------------------------------------------------
// 测验进程
//---------------------------------------------------------------
int main() {
good_code();
bad_code();
mem_stack.Print();
system("PAUSE");
return 0;
}

其思路:每次new中拓荒一块内存就用链表把这个内存的信息保存下来,每次用delete删去一块内存就从链表中删去这块内存的记载。

malloc和free的办法也相同。用宏的办法重完成malloc和free。

进阶2

还有没有其他的办法呢?当然有啦,便是选用智能指针(C++),这部分讲起来内容会比较多。只提供个思路吧。

终极

很明显,终极处理内存走漏问题的办法便是杰出的编码习气。运用内存分配函数,一旦开湖南幸运赛车开奖直播-怎样处理Linux内存走漏?释结束,记住开释。这一部分,需求各位开发人员多多编码。自己有对内存分配函数的一种敬畏。时间记住内存的开释。

好了,今日的文章就到这儿吧。共享是一种高兴,也是自我总结途径。



上一条      下一条
返回顶部