久久99精品久久久久久琪琪,久久人人爽人人爽人人片亞洲,熟妇人妻无码中文字幕,亚洲精品无码久久久久久久

檢查內存泄露五篇

時間:2019-05-15 14:56:14下載本文作者:會員上傳
簡介:寫寫幫文庫小編為你整理了多篇相關的《檢查內存泄露》,但愿對你工作學習有幫助,當然你在寫寫幫文庫還可以找到更多《檢查內存泄露》。

第一篇:檢查內存泄露

Debug Assertion Failed!

這個錯誤的原因可能是數組越界或出現了野指針.內存釋放(或資源釋放)時出現了錯誤

這是個很一般性的錯誤, 就像Windows報告說執行了非法操作一樣.憑此信息無法判 斷具體錯誤位置, 只能靠自己跟蹤了

當出現這個錯誤的時候,我重新檢查了自己new的指針,由于對于這塊很發怵,所以把所有new的指針都避掉。但還是出現同樣的問題。

后來又上網搜了一下,在《VC++6.0中內存泄漏檢測》這篇文章中提到,“可用于被多態繼承的基類其析構函數應當有virtual修飾“的法則(一不小心就忘了寫virtual ^_^),”,哈哈,我也違反了,后來加上virtual后就沒有問題了。

下面把那篇文章貼上來以供自己日后查看。

VC++6.0中內存泄漏檢測(轉)

VC++6.0中內存泄漏檢測

這篇文章是對2004-09-02日發表的《VC++6.0中簡單的內存泄漏檢測事例代碼》(已經刪除)的更新.對C++代碼而言,內存泄漏問題雖然有諸多方法避免,但實際代碼編寫的時候,或出于自信或出于復雜性的考慮,常常還會用到原始的operator new,這不可避免的會帶來內存泄漏的可能,不久前本人因為違反了”可用于被多態繼承的基類其析構函數應當有virtual修飾“的法則(一不小心就忘了寫virtual ^_^),導致了內存泄漏,因此我覺得出于安全考慮,在代碼中加入內存泄漏檢查機制還是很必要的,也因為這次的內存泄漏事件促使我寫出這一篇文章.VC++中本身就有內存泄漏檢查的機制,你可以在向導生成的支持MFC的工程中看到如下代碼:

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

通過它們,你能非常容易的發現代碼中的內存泄漏,但是如果手工將這個功能移植到非MFC工程中去是很繁瑣的一件事,另外它還有一個bug,在多線程并發調用這個DEBUG_NEW時會導致系統級錯誤,因此本人在此重寫了這個功能,將以下的debug_new.h和debug_new.cpp添加到工程中,并在需要檢測的cpp中#include ”debug_new.h“和main中一開始處加入REG_DEBUG_NEW宏即可.1.debug_new.h 源代碼

/************************************************************************/ /* comment: 此文件與debug_new.cpp配合使用,用于在調試期發現內存泄漏 */

/* 僅在VC++編譯器中適用(包括Intel C++,因為它使用了相同的庫)*/

/* 作者: 周星星*/

/* 版權申明: 無,可任意 使用,修改 和 發布 */

/************************************************************************/ /* sample

#include

#include ”debug_new.h“ // +

using namespace std;

int main(void)

{

REG_DEBUG_NEW;// +

char* p = new char[2];

cout << ”--End--“ << endl;

return 0;

}

在VC++ IDE中按F5調試運行將會在Output窗口的Debug頁看到類似如下的提示: Dumping objects->

d:test.cpp(10): {45} normal block at 0x003410C8, 2 bytes long.Data: < > CD CD

Object dump complete.如果不出現如上提示請Rebuild All一次.*/

#ifndef _DEBUG_NEW_H_

#define _DEBUG_NEW_H_

#ifdef _DEBUG

#undef new

extern void _RegDebugNew(void);

extern void* __cdecl operator new(size_t, const char*, int);

extern void __cdecl operator delete(void*, const char*, int);

#define new new(__FILE__, __LINE__)

#define REG_DEBUG_NEW _RegDebugNew();

#else

#define REG_DEBUG_NEW

#endif // _DEBUG

#endif // _DEBUG_NEW_H_

2.debug_new.cpp 源代碼

/************************************************************************/ /* comment: 此文件與debug_new.h配合使用,用于在調試期發現內存泄漏 */

/* 僅在VC++編譯器中適用(包括Intel C++,因為它使用了相同的庫)*/

/* 作者: 周星星*/

/* 版權申明: 無,可任意 使用,修改 和 發布 */

/************************************************************************/ //#include ”debug_new.h“

#ifdef _DEBUG

#include

#include

class _CriSec

{

CRITICAL_SECTION criSection;

public:

_CriSec(){ InitializeCriticalSection(&criSection);}

~_CriSec(){ DeleteCriticalSection(&criSection);}

void Enter(){ EnterCriticalSection(&criSection);}

void Leave(){ LeaveCriticalSection(&criSection);}

} _cs;

void _RegDebugNew(void)

{

_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG | _CRTDBG_LEAK_CHECK_DF);

}

void* __cdecl operator new(size_t nSize, const char* lpszFileName, int nLine)

{

// comment 1: MFC中提供的debug new雖然加了鎖,但我在實際測試的時候發現多線程并發 // 調用的時候還是拋出了系統錯誤,所以我在這里加了一個線程互斥量.// comment 2: debug new和debug delete之間需不需要互斥我并不知道,保險起見,我同樣 // 加了線程互斥量.// comment 3: 按照C++標準規定,在operator new失敗后應當調用set_new_handler設置的 // 函數,但是MSDN中卻說”頭文件new中的set_new_handler是stub的,而應該使 // 用頭文件new.h中的_set_new_handler“,這簡直是滑天下之大稽.// 以下是VC++6.0中的set_new_handler定義:

// new_handler __cdecl set_new_handler(new_handler new_p)

// {

// assert(new_p == 0);// cannot use stub to register a new handler

// _set_new_handler(0);

// return 0;

// }

// 所以我也無計可施,只能舍棄set_new_handler的作用._cs.Enter();

void* p = _malloc_dbg(nSize, _NORMAL_BLOCK, lpszFileName, nLine);

_cs.Leave();

return p;

}

void __cdecl operator delete(void* p, const char* /*lpszFileName*/, int /*nLine*/)

{

_cs.Enter();

_free_dbg(p, _CLIENT_BLOCK);

_cs.Leave();

}

#endif

3.事例代碼

#include

#include ”debug_new.h“

using namespace std;

int main(void)

{

REG_DEBUG_NEW;

char* p = new char[2];

p[0] = 'A';

p[1] = 'B';

cout << ”--End--" << endl;

return 0;

}

4.結果輸出

在VC++ IDE中按F5調試運行將會在Output窗口的Debug頁看到類似如下的提示: ……

Dumping objects->

d:test.cpp(10): {45} normal block at 0x003410C8, 2 bytes long.Data: 41 42

Object dump complete.……

第二篇:性能測試總結之內存泄露和內存溢出

性能測試總結之內存泄露和內存溢出

主要從以下幾部分來說明,關于內存和內存泄露、溢出的概念,區分內存泄露和內存溢出;內存的區域劃分,了解GC回收機制;重點關注如何去監控和發現內存問題;此外分析出問題還要如何解決內存問題。

下面就開始本篇的內容:

第一部分 概念

眾所周知,java中的內存java虛擬機自己去管理的,他不想C++需要自己去釋放。籠統地去 講,java的內存分配分為兩個部分,一個是數據堆,一個是棧。程序在運行的時候一般分配數據堆,把局部的臨時的變量都放進去,生命周期和進程有關系。但 是如果程序員聲明了static的變量,就直接在棧中運行的,進程銷毀了,不一定會銷毀static變量。

另外為了保證java內存不會溢出,java中有垃圾回收機制。System.gc()即垃圾收集機制是指jvm用于釋放那些不再使用的對象所占用的內存。java語言并不要求jvm有gc,也沒有規定gc如何工作。垃圾收集的目的在于清除不再使用的對象。gc通過確定對象是否被活動對象引用來確定是否收集該對象。

而其中,內存溢出就是你要求分配的java虛擬機內存超出了系統能給你的,系統不能滿足需求,于是產生溢出。

內存泄漏是指你向系統申請分配內存進行使用(new),可是使用完了以后卻不歸還(delete),結果你申請到的那塊內存你自己也不能再訪問,該塊已分配出來的內存也無法再使用,隨著服務器內存的不斷消耗,而無法使用的內存越來越 多,系統也不能再次將它分配給需要的程序,產生泄露。一直下去,程序也逐漸無內存使用,就會溢出。

第二部分 原理

JAVA垃圾回收及對內存區劃分

在Java虛擬機規范中,提及了如下幾種類型的內存空間:

◇ 棧內存(Stack):每個線程私有的。

◇ 堆內存(Heap):所有線程公用的。

◇ 方法區(Method Area):有點像以前常說的“進程代碼段”,這里面存放了每個加載類的反射信息、類函數的代碼、編譯時常量等信息。

◇ 原生方法棧(Native Method Stack):主要用于JNI中的原生代碼,平時很少涉及。

而Java的使用的是堆內存,java堆是一個運行時數據區,類的實例(對象)從中分配空間。Java虛擬機(JVM)的堆中儲存著正在運行的應用程序所建立的所有對象,“垃圾回收”也是主要是和堆內存(Heap)有關。

垃圾回收的概念就是JAVA虛擬機(JVM)回收那些不再被引用的對象內存的過程。一般我們認為正在被引用的對象狀態為“alive”,而沒有 被應用或者取不到引用屬性的對象狀態為“dead”。垃圾回收是一個釋放處于”dead”狀態的對象的內存的過程。而垃圾回收的規則和算法被動態的作用于 應用運行當中,自動回收。

JVM的垃圾回收器采用的是一種分代(generational)回收策略,用較高的頻率對年輕的對象(young generation)進行掃描和回收,這種叫做minor collection,而對老對象(old generation)的檢查回收頻率要低很多,稱為major collection。這樣就不需要每次GC都將內存中所有對象都檢查一遍,這種策略有利于實時觀察和回收。

(Sun JVM 1.3 有兩種最基本的內存收集方式:一種稱為copying或scavenge,將所有仍然生存的對象搬到另外一塊內存后,整塊內存就可回收。這種方法有效率,但需要有一定的空閑內存,拷貝也有開銷。這種方法用于minor collection。另外一種稱為mark-compact,將活著的對象標記出來,然后搬遷到一起連成大塊的內存,其他內存就可以回收了。這種方法不 需要占用額外的空間,但速度相對慢一些。這種方法用于major collection.)

一些對象被創建出來只是擁有短暫的生命周期,比如 iterators 和本地變量。

另外一些對象被創建是擁有很長的生命周期,比如 高持久化對象等。

垃圾回收器的分代策略是把內存區劃分為幾個代,然后為每個代分配一到多個內存區塊。當其中一個代用完了分配給他的內存后,JVM會在分配的內存 區內執行一個局部的GC(也可以叫minor collection)操作,為了回收處于“dead”狀態的對象所占用的內存。局部GC通常要不Full GC要快很多。

JVM定義了兩個代,年輕代(yong generation)(有時稱為“nursery”托兒所)和老年代(old generation)。年輕代包括 “Eden space(伊甸園)”和兩個“survivor spaces”。虛擬內存初始化的時候會把所有對象都分配到 Eden space,并且大部分對象也會在該區域被釋放。當進行 minor GC的時候,VM會把剩下的沒有釋放的對象從Eden space移動到其中一個survivor spaces當中。此外,VM也會把那些長期存活在survivor spaces 里的對象移動到 老生代的“tenured” space中。當 tenured generation 被填滿后,就會產生Full GC,Full GC會相對比較慢因為回收的內容包括了所有的 live狀態的對象。pemanet generation這個代包括了所有java虛擬機自身使用的相對比較穩定的數據對象,比如類和對象方法等。

關于代的劃分,可以從下圖中獲得一個概況:

如果垃圾回收器影響了系統的性能,或者成為系統的瓶頸,你可以通過自定義各個代的大小來優化它的性能。使用JConsole,可以方便的查看到當前應用所配置的垃圾回收器的各個參數。想要獲得更詳細的參數,可以參考以下調優介紹:

Tuning Garbage collection with the 5.0 HotSpot VM

http://java.sun.com/docs/hotspot/gc/index.html

最后,總結一下各區內存:

Eden Space(heap): 內存最初從這個線程池分配給大部分對象。

Survivor Space(heap):用于保存在eden space內存池中經過垃圾回收后沒有被回收的對象。

Tenured Generation(heap):用于保持已經在 survivor space內存池中存在了一段時間的對象。

Permanent Generation(non-heap): 保存虛擬機自己的靜態(refective)數據,例如類(class)和方法(method)對象。Java虛擬機共享這些類數據。這個區域被分割為只讀的和只寫的,Code Cache(non-heap):HotSpot Java虛擬機包括一個用于編譯和保存本地代碼(native code)的內存,叫做“代碼緩存區”(code cache)

第三部分 監控(工具發現問題)

談到內存監控工具,JConsole是必須要介紹的,它是一個用JAVA寫的GUI程序,用來監控 VM,并可監控遠程的VM,易用且功能強大。具體可監控JAVA內存、JAVA CPU使用率、線程執行情況、加載類概況等,Jconsole需要在JVM參數中配置端口才能使用。

由于是GUI程序,界面可視化,這里就不做詳細介紹,具體幫助支持文檔請參閱性能測試JConsole使用方法總結:

http://

http://Java.sun.com/javase/6/docs/technotes/tools/share/jconsole.html

在實際測試某一個項目時,內存出現泄露現象。起初在性能測試的1個小時中,并不明顯,而在穩定性測試的時候才發現,應用的HSF調用在經過幾個 小時運行后,就出現性能明顯下降的情況。在服務日志中報大量HSF超時,但所調用系統沒有任何超時日志,并且壓力應用的load都很低。經過查看日志后,認為應用可能存在內存泄漏。通過jconsole 以及 jmap 工具進行分析發現,確實存在內存泄漏問題,其中PS Old Gen最終達到占用 100%的占用。如圖所示:

從上圖可以看到,雖然每次Full GC,JVM內存會有部分回收,但回收并不徹底,不可回收的內存對象會越來越多,這樣便會出現以上的一個趨勢。在Full GC無法回收的對象越來越多時,最終已使用內存達到系統分配的內存最大值,系統最后無內存可分配,最終down機。

第四部分 分析

經過開發和架構師對應用的分析,查看此時內存隊列,看哪個對象占用數據最多,再利用jmap命令,對線程數據分析,如下所示:

num #instances #bytes class name

1: 9248056 665860032 com.taobao.matrix.mc.domain.**

2: 9248031 295936992 com.taobao.matrix.**

3: 9248068 147969088 java.util.**

4: 1542111 37010664 java.util.Date

前三個instances不斷增加,指代的是同一個代碼邏輯,異步分發的問題,堵塞消息,回收多次都無法回收成功。導致內存溢出。

此外,對應用的性能單獨做了壓測,他的性能只能支撐到一半左右,故發送消息的TPS,應用肯定無法處理過來,導致消息堆積,而JAVA垃圾回收期認為這些都是有用的對象,導致內存堆積,直至系統崩潰。

調優方法

由于具體調優方法涉及到應用的配置信息,故在此暫不列出,可以參考性能測試小組發布的《性能測試調優寶典》

第四部分 總結

內存溢出主要是由于代碼編寫時對某些方法、類應用不合理,或者沒有預估到臨時對象會占用很大內存量,或者把過多的數據放入JVM緩存,或者性能 壓力大導致消息堆積而占用內存,以至于在性能測試時,生成龐大數量的臨時對象,GC時沒有做出有效回收甚至根本就不能回收,造成內存空間不足,內存溢出。

如果編碼之前,對內存使用量進行預估,對放在內存中的數據進行評估,保證有用的信息盡快釋放,無用的信息能夠被GC回收,這樣在一定程度上是可以避免內存溢出問題的。

第三篇:C與C 經典面試題(內存泄露)匯總

C、C++語言面試題2007-07-15 18:57 1.已知strcpy 函數的原型是:

char *strcpy(char *strDest, const char *strSrc);其中strDest 是目的字符串,strSrc 是源字符串。不調用C++/C 的字符串庫函數,請編寫函數 strcpy 答案:

char *strcpy(char *strDest, const char *strSrc){ if(strDest == NULL || strSrc == NULL)return NULL;if(strDest == strSrc)return strDest;char *tempptr = strDest;while((*strDest++ = *strSrc++)!= ‘

主站蜘蛛池模板: 欧美乱妇无乱码大黄a片| 边做饭边被躁bd苍井空图片| 国产亚洲精品久久久久久青梅| 中国熟妇人妻xxxxx| 夜夜春亚洲嫩草影院| 亚洲国产精品无码久久久秋霞2| 久久久亚洲欧洲日产国码aⅴ| 久久强奷乱码老熟女网站| 在线精品自偷自拍无码中文| 一个人看的www免费视频在线观看| 又色又爽又黄的视频软件app| 18禁止进入1000部高潮网站| 人妻丰满熟妇av无码片| 国产一卡2卡3卡四卡精品网站| 人人操人人妻| av天堂亚洲狼人在线| 一边捏奶头一边高潮视频| 欧洲熟妇精品视频| 不卡一区二区视频日本| 亚洲 欧洲 日韩 综合二区| 被窝的午夜无码福利专区| 熟女人妻少妇精品视频| 国产做床爱无遮挡免费视频| 精品久久久久久中文字幕| 国产亚洲精品一区二三区| 国产精品久久久久久久久久久久午夜片| 人人爽人人爽人人爽| 亚洲另类成人小说综合网| 亚洲色偷偷偷网站色偷一区| 夜夜揉揉日日人人| 国产午夜精品久久精品电影| 亲子乱aⅴ一区二区三区| 久久国产午夜精品理论片| 国色天香国产精品| 精品久久久久久无码中文野结衣| 国产无遮挡又黄又爽在线视频| 国产在线精品99一区不卡| 亚洲中文无码av在线| 久久久久88色偷偷| 亚洲欧美日韩综合久久久久| 久久电影网午夜鲁丝片免费|