1、內存泄漏指由於疏忽或錯誤造成程序未能釋放已經不再使用的內存的情況。
2、一般我們常說的內存泄漏是指堆內存的泄漏。堆內存是指程序從堆中分配的,大小任意的,
使用完後必須顯式釋放的內存。應用程序一般使用malloc,calloc,realloc,new等函數從堆
中分配到一塊內存,使用完後,程序必須負責相應的調用free或delete釋放該內存塊,否則
這塊內存就不能被再次使用,就是這塊內存泄漏了。
3、內存泄露多數屬於程序本身設計問題,有以下幾種解決方法:
1)從程序內部重新編譯。養成良好的編碼習慣,盡量在涉及內存的程序段,檢測出內存泄露。
2)結束程序,內存自然就會被操作系統回收。
3)重新啟動電腦後,立刻恢復。
㈡ 如何檢查內存泄露問題
簡單說明了一下沒有工具的情況如何運用VC庫中的工具來檢查代碼的內存泄漏問題。
一: 內存泄漏
內存泄漏是編程中常常見到的一個問題,內存泄漏往往會一種奇怪的方式來表現出來,基本上每個程序都表現出不同的方式。 但是一般最後的結果只有兩個,一個是程序當掉,一個是系統內存不足。 還有一種就是比較介於中間的結果程序不會當,但是系統的反映時間明顯降低,需要定時的Reboot才會正常。
有 一個很簡單的辦法來檢查一個程序是否有內存泄漏。就是是用Windows的任務管理器(Task Manager)。運行程序,然後在任務管理器裡面查看 「內存使用」和」虛擬內存大小」兩項,當程序請求了它所需要的內存之後,如果虛擬內存還是持續的增長的話,就說明了這個程序有內存泄漏問題。 當然如果內存泄漏的數目非常的小,用這種方法可能要過很長時間才能看的出來。
當然最簡單的辦法大概就是用CompuWare的BoundChecker 之類的工具來檢測了,不過這些工具的價格對於個人來講稍微有點奢侈了。
如果是已經發布的程序,檢查是否有內存泄漏是又費時又費力。所以內存泄漏應該在Code的生成過程就要時刻進行檢查。
二: 原因
內存泄漏產生的原因一般是三種情況:
分配完內存之後忘了回收;
程序Code有問題,造成沒有辦法回收;
某些API函數操作不正確,造成內存泄漏。
1. 內存忘記回收,這個是不應該的事情。但是也是在代碼種很常見的問題。分配內存之後,用完之後,就一定要回收。如果不回收,那就造成了內存的泄漏,造成內存泄漏的Code如果被經常調用的話,那內存泄漏的數目就會越來越多的。從而影響整個系統的運行。比如下面的代碼:
for (int =0;I<100;I++)
{
Temp = new BYTE[100];
}
就會產生 100*100Byte的內存泄漏。
2. 在某些時候,因為代碼上寫的有問題,會導致某些內存想回收都收不回來,比如下面的代碼:
Temp1 = new BYTE[100];
Temp2 = new BYTE[100];
Temp2 = Temp1;
這樣,Temp2的內存地址就丟掉了,而且永遠都找不回了,這個時候Temp2的內存空間想回收都沒有辦法。
3. API函 數應用不當,在Windows提供API函數裡面有一些特殊的API,比如FormatMessage。 如果你給它參數中有FORMAT_MESSAGE_ALLOCATE_BUFFER,它會在函數內部New一塊內存Buffer出來。但是這個 buffer需要你調用LocalFree來釋放。 如果你忘了,那就會產生內存泄漏。
三: 檢查方法
一 般的內存泄漏檢查的確是很困難,但是也不是完全沒有辦法。如果你用VC的庫來寫東西的話,那麼很幸運的是,你已經有了很多檢查內存泄漏的工具,只是你想不 想用的問題了。Visual C++的Debug版本的C運行庫(C Runtime Library)。它已經提供好些函數來幫助你診斷你的代碼和跟蹤內存泄漏。 而且最方便的地方是這些函數在Release版本中完全不起任何作用,這樣就不會影響你的Release版本程序的運行效率。
比如下面的例子裡面,有一個明細的內存泄漏。當然如果只有這么幾行代碼的話,是很容易看出有內存泄漏的。但是想在成千上萬行代碼裡面檢查內存泄漏問題就不是那麼容易了。
char * pstr = new char[5];
lstrcpy(pstr,"Memory leak");
如 果我們在Debug版本的Code裡面對堆(Heap)進行了操作,包括malloc, free, calloc, realloc, new 和 delete可以利用VC Debug運行時庫中堆Debug函數來做堆的完整性和安全性檢查。比如上面的代碼,lstrcpy的操作明顯破壞了pstr的堆結構。使其溢出,並破壞 了臨近的數據。那我們可以在調用lstrcpy之後的代碼裡面加入 _CrtCheckMemory函數。_CrtCheckMemory函數發現前面的lstrcpy使得pstr的堆結構被破壞,會輸出這樣的報告:
emory check error at 0x00372FA5 = 0x79, should be 0xFD.
memory check error at 0x00372FA6 = 0x20, should be 0xFD.
memory check error at 0x00372FA7 = 0x6C, should be 0xFD.
memory check error at 0x00372FA8 = 0x65, should be 0xFD.
DAMAGE: after Normal block (#41) at 0x00372FA0.
Normal located at 0x00372FA0 is 5 bytes long.
它 告訴說 pstr的長度應該時5個Bytes,但是在5Bytes後面的幾個Bytes也被非法改寫了。提醒你產生了越界操作。_CrtCheckMemory 的返回值只有TRUE和FALSE,那麼你可以用_ASSERTE()來報告出錯信息。 上面的語句可以換成 _ASSERTE(_CrtCheckMemory()); 這樣Debug版本的程序在運行的時候就會彈出一個警告對話框,這樣就不用在運行時候一直盯著Output窗口看了。這個時候按Retry,就可以進入源 代碼調試了。看看問題到底出在哪裡。
其他類似的函數還有 _CrtDbgReport, _CrtDoForAllClientObjects, _CrtDumpMemoryLeaks,_CrtIsValidHeapPointer, _CrtIsMemoryBlock, _CrtIsValidPointer,_CrtMemCheckpoint, _CrtMemDifference, _CrtMemDumpAllObjectsSince, _CrtMemDumpStatistics, _CrtSetAllocHook, _CrtSetBreakAlloc, _CrtSetDbgFlag,_CrtSetDumpClient, _CrtSetReportFile, _CrtSetReportHook, _CrtSetReportMode
這 些函數全部都可以用來在Debug版本中檢查內存的使用情況。具體怎麼使用這些函數就不在這里說明了,各位可以去查查MSDN。在這些函數中用處比較大 的,或者說使用率會比較高的函數是_CrtMemCheckpoint, 設置一個內存檢查點。這個函數會取得當前內存的運行狀態。 _CrtMemDifference 檢查兩種內存狀態的異同。 _CrtMemDumpAllObjectsSince 從程序運行開始,或者從某個內存檢查點開始Dump出堆中對象的信息。還有就是_CrtDumpMemoryLeaks當發生內存溢出的時候Dump出堆 中的內存信息。 _CrtDumpMemoryLeaks一般都在有懷疑是內存泄漏的代碼後面調用。比如下面的例子:
#include <windows.h>
#include <crtdbg.h>
void main()
{
char * pstr;
pstr = new char[5];
_CrtDumpMemoryLeaks();
}
輸出:
Detected memory leaks! à提醒你,代碼有內存泄漏.
Dumping objects ->
{44} normal block at 0x00372DB8, 5 bytes long.
Data: < > CD CD CD CD CD
Object mp complete.
如 果你雙擊包含行文件名的輸出行,指針將會跳到源文件中內存被分配地方的行。當無法確定那些代碼產生了內存泄漏的時候,我們就需要進行內存狀態比較。在可疑 的代碼段的前後設置內存檢查點,比較內存使用是否有可疑的變化。以確定內存是否有泄漏。為此要先定義三個_CrtMemState 對象來保存要比較的內存狀態。兩個是用來比較,一個用了保存前面兩個之間的區別。
_CrtMemState Sh1,Sh2,Sh_Diff;
char *pstr1 = new char[100];
_CrtMemCheckPoint(&Sh1); ->設置第一個內存檢查點
char *pstr2 = new char[100];
_CrtMemCheckPoint(&Sh2); ->設置第二個內存檢查點
_CrtMemDifference(&Sh_Diff, &Sh1, &Sh2); ->檢查變化
_CrtMemDumpAllObjectsSince(&Sh_Diff); ->Dump變化
如 果你的程序中使用了MFC類庫,那麼內存泄漏的檢查方法就相當的簡單了。因為Debug版本的MFC本身就提供一部分的內存泄漏檢查。 大部分的new 和delete沒有配對使用而產生的內存泄漏,MFC都會產生報告。這個主要是因為MFC重載了Debug版本的new 和delete操作符, 並且對前面提到的API函數重新進行了包裝。在MFC類庫中檢查內存泄漏的Class就叫 CMemoryState,它重新包裝了了_CrtMemState,_CrtMemCheckPoint, _CrtMemDifference, _CrtMemDumpAllObjectsSince這些函數。並對於其他的函數提供了Afx開頭的函數,供MFC程序使用。比如 AfxCheckMemory, AfxDumpMemoryLeaks 這些函數的基本用法同上面提到的差不多。 CMemoryState和相關的函數的定義都在Afx.h這個頭文件中。 有個簡單的辦法可以跟蹤到這些函數的聲明。在VC中找到MFC程序代碼中下面的代碼, 一般都在X.cpp的開頭部分
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
把 游標移到DEBUG_NEW上面 按F12,就可以進入Afx.h中定義這些Class和函數的代碼部分。 VC中內存泄漏的常規檢查辦法主要是上面的兩種。當然這兩種方法只是針對於Debug版本的Heap的檢查。如果Release版本中還有內存泄漏,那麼 檢查起來就麻煩很多了。
4 .總結:
實際上Heap的內存泄漏問題是相當的好查的。VC的提供的檢查工具也不太少,但是如果是棧出了什麼問題,恐怕就麻煩很多了。棧出問題,一般不會產生內存泄漏,但是你的代碼的邏輯上很有可能會有影響。這個是最最痛苦的事情。 編程,就是小心,小心再小心而已。
㈢ 常見的內存泄漏原因及解決方法
(Memory Leak,內存泄漏)
當一個對象已經不需要再使用本該被回收時,另外一個正在使用的對象持有它的引用從而導致它不能被回收,這導致本該被回收的對象不能被回收而停留在堆內存中,這就產生了內存泄漏。
內存泄漏是造成應用程序OOM的主要原因之一。我們知道Android系統為每個應用程序分配的內存是有限的,而當一個應用中產生的內存泄漏比較多時,這就難免會導致應用所需要的內存超過系統分配的內存限額,這就造成了內存溢出從而導致應用Crash。
因為內存泄漏是在堆內存中,所以對我們來說並不是可見的。通常我們可以藉助MAT、LeakCanary等工具來檢測應用程序是否存在內存泄漏。
1、MAT是一款強大的內存分析工具,功能繁多而復雜。
2、LeakCanary則是由Square開源的一款輕量級的第三方內存泄漏檢測工具,當檢測到程序中產生內存泄漏時,它將以最直觀的方式告訴我們哪裡產生了內存泄漏和導致誰泄漏了而不能被回收。
由於單例的靜態特性使得其生命周期和應用的生命周期一樣長,如果一個對象已經不再需要使用了,而單例對象還持有該對象的引用,就會使得該對象不能被正常回收,從而導致了內存泄漏。
示例:防止單例導致內存泄漏的實例
這樣不管傳入什麼Context最終將使用Application的Context,而單例的生命周期和應用的一樣長,這樣就防止了內存泄漏。???
例如,有時候我們可能會在啟動頻繁的Activity中,為了避免重復創建相同的數據資源,可能會出現如下寫法:
這樣在Activity內部創建了一個非靜態內部類的單例,每次啟動Activity時都會使用該單例的數據。雖然這樣避免了資源的重復創建,但是這種寫法卻會造成內存泄漏。因為非靜態內部類默認會持有外部類的引用,而該非靜態內部類又創建了一個靜態的實例,該實例的生命周期和應用的一樣長,這就導致了該靜態實例一直會持有該Activity的引用,從而導致Activity的內存資源不能被正常回收。
解決方法 :將該內部類設為靜態內部類或將該內部類抽取出來封裝成一個單例,如果需要使用Context,就使用Application的Context。
示例:創建匿名內部類的靜態對象
1、從Android的角度
當Android應用程序啟動時,該應用程序的主線程會自動創建一個Looper對象和與之關聯的MessageQueue。當主線程中實例化一個Handler對象後,它就會自動與主線程Looper的MessageQueue關聯起來。所有發送到MessageQueue的Messag都會持有Handler的引用,所以Looper會據此回調Handle的handleMessage()方法來處理消息。只要MessageQueue中有未處理的Message,Looper就會不斷的從中取出並交給Handler處理。另外,主線程的Looper對象會伴隨該應用程序的整個生命周期。
2、 Java角度
在Java中,非靜態內部類和匿名類內部類都會潛在持有它們所屬的外部類的引用,但是靜態內部類卻不會。
對上述的示例進行分析,當MainActivity結束時,未處理的消息持有handler的引用,而handler又持有它所屬的外部類也就是MainActivity的引用。這條引用關系會一直保持直到消息得到處理,這樣阻止了MainActivity被垃圾回收器回收,從而造成了內存泄漏。
解決方法 :將Handler類獨立出來或者使用靜態內部類,這樣便可以避免內存泄漏。
示例:AsyncTask和Runnable
AsyncTask和Runnable都使用了匿名內部類,那麼它們將持有其所在Activity的隱式引用。如果任務在Activity銷毀之前還未完成,那麼將導致Activity的內存資源無法被回收,從而造成內存泄漏。
解決方法 :將AsyncTask和Runnable類獨立出來或者使用靜態內部類,這樣便可以避免內存泄漏。
對於使用了BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap等資源,應該在Activity銷毀時及時關閉或者注銷,否則這些資源將不會被回收,從而造成內存泄漏。
1)比如在Activity中register了一個BraodcastReceiver,但在Activity結束後沒有unregister該BraodcastReceiver。
2)資源性對象比如Cursor,Stream、File文件等往往都用了一些緩沖,我們在不使用的時候,應該及時關閉它們,以便它們的緩沖及時回收內存。它們的緩沖不僅存在於 java虛擬機內,還存在於java虛擬機外。如果我們僅僅是把它的引用設置為null,而不關閉它們,往往會造成內存泄漏。
3)對於資源性對象在不使用的時候,應該調用它的close()函數將其關閉掉,然後再設置為null。在我們的程序退出時一定要確保我們的資源性對象已經關閉。
4)Bitmap對象不在使用時調用recycle()釋放內存。2.3以後的bitmap應該是不需要手動recycle了,內存已經在java層了。
初始時ListView會從BaseAdapter中根據當前的屏幕布局實例化一定數量的View對象,同時ListView會將這些View對象緩存起來。當向上滾動ListView時,原先位於最上面的Item的View對象會被回收,然後被用來構造新出現在下面的Item。這個構造過程就是由getView()方法完成的,getView()的第二個形參convertView就是被緩存起來的Item的View對象(初始化時緩存中沒有View對象則convertView是null)。
構造Adapter時,沒有使用緩存的convertView。
解決方法 :在構造Adapter時,使用緩存的convertView。
我們通常把一些對象的引用加入到了集合容器(比如ArrayList)中,當我們不需要該對象時,並沒有把它的引用從集合中清理掉,這樣這個集合就會越來越大。如果這個集合是static的話,那情況就更嚴重了。
解決方法 :在退出程序之前,將集合里的東西clear,然後置為null,再退出程序。
當我們不要使用WebView對象時,應該調用它的destory()函數來銷毀它,並釋放其佔用的內存,否則其長期佔用的內存也不能被回收,從而造成內存泄露。
解決方法 :為WebView另外開啟一個進程,通過AIDL與主線程進行通信,WebView所在的進程可以根據業務的需要選擇合適的時機進行銷毀,從而達到內存的完整釋放。
1、在涉及使用Context時,對於生命周期比Activity長的對象應該使用Application的Context。凡是使用Context優先考慮Application的Context,當然它並不是萬能的,對於有些地方則必須使用Activity的Context。對於Application,Service,Activity三者的Context的應用場景如下:
其中,NO1表示Application和Service可以啟動一個Activity,不過需要創建一個新的task任務隊列。而對於Dialog而言,只有在Activity中才能創建。除此之外三者都可以使用。
2、對於需要在靜態內部類中使用非靜態外部成員變數(如:Context、View ),可以在靜態內部類中使用弱引用來引用外部類的變數來避免內存泄漏。
3、對於不再需要使用的對象,顯示的將其賦值為null,比如使用完Bitmap後先調用recycle(),再賦為null。
4、保持對對象生命周期的敏感,特別注意單例、靜態對象、全局性集合等的生命周期。
5、對於生命周期比Activity長的內部類對象,並且內部類中使用了外部類的成員變數,可以這樣做避免內存泄漏:
1)將內部類改為靜態內部類
2)靜態內部類中使用弱引用來引用外部類的成員變數
Android內存泄漏總結
㈣ 怎樣發現內存泄露
一、內存泄漏的檢查方法:
1.ccmalloc-Linux和Solaris下對C和C++程序的簡單的使用內存泄漏和malloc調試庫。
2.Dmalloc-Debug Malloc Library.
3.Electric Fence-Linux分發版中由Bruce Perens編寫的malloc()調試庫。
4.Leaky-Linux下檢測內存泄漏的程序。
5.LeakTracer-Linux、Solaris和HP-UX下跟蹤和分析C++程序中的內存泄漏。
6.MEMWATCH-由Johan Lindh編寫,是一個開放源代碼C語言內存錯誤檢測工具,主要是通過gcc的precessor來進行。
7.Valgrind-Debugging and profiling Linux programs, aiming at programs written in C and C++.
8.KCachegrind-A visualization tool for the profiling data generated by Cachegrind and Calltree.
9.IBM Rational PurifyPlus-幫助開發人員查明C/C++、託管.NET、Java和VB6代碼中的性能和可靠性錯誤。PurifyPlus 將內存錯誤和泄漏檢測、應用程序性能描述、代碼覆蓋分析等功能組合在一個單一、完整的工具包中。
二、內存泄漏的簡單介紹:
內存泄漏也稱作「存儲滲漏」,用動態存儲分配函數動態開辟的空間,在使用完畢後未釋放,結果導致一直占據該內存單元。直到程序結束。(其實說白了就是該內存空間使用完畢之後未回收)即所謂內存泄漏。
內存泄漏形象的比喻是「操作系統可提供給所有進程的存儲空間正在被某個進程榨乾」,最終結果是程序運行時間越長,佔用存儲空間越來越多,最終用盡全部存儲空間,整個系統崩潰。所以「內存泄漏」是從操作系統的角度來看的。這里的存儲空間並不是指物理內存,而是指虛擬內存大小,這個虛擬內存大小取決於磁碟交換區設定的大小。由程序申請的一塊內存,如果沒有任何一個指針指向它,那麼這塊內存就泄漏了。
㈤ 如何判斷內存泄漏
內存泄露是指使用內存完成後沒有釋放,內存增長並不能分辨增長出來的內存是進程真正要用的,還是進程泄露出來的。而CPU的佔用是瞬時的、確定的,不存在某個進程申請了CPU占著不用的情況。在穩定性測試(也叫持久測試或疲勞測試)中,需要觀察內存是否有泄露。然而使用內存的進程千千萬,整個伺服器的內存增長似乎也不能判斷某個進程的內存有泄露。因此在穩定性測試過程中往往需要全程關注指定進程的內存消耗,比如運行3天、7天。
查看內存使用情況的命令有ps、sar、svmon、vmstat等等,但本文並不從工具使用的角度來介紹,而是從性能測試中關注指標的角度來介紹。如果採用其他命令查看內存,需注意,相似的名字在不同命令當中的含義是不一樣的,一定要搞清楚這個欄位的真正含義。
例1:Virtual這個詞,有時候在內存裡面指Paging Space(換頁空間),有時指進程空間裡面佔用的所有分頁(包括物理內存和Paging Space中的分頁)。
例2:Nmon中的PgIn/PgOut、topas中的PageIn/PageOut是指對文件系統的換頁,而vmstat中的pi/po是對Paging Space的換頁,而topas P中進程的PAGE SPACE是指進程的Data Segment。
㈥ 25. 什麼是內存泄漏,怎樣最簡單的方法判斷被存泄漏
一般我們常說的內存泄漏是指堆內存的泄漏。堆內存是指程序從堆中分配的,大小任意的(內存塊的大小可以在程序運行期決定),使用完後必須顯示釋放的內存。應用程序一般使用malloc,realloc,new等函數從堆中分配到一塊內存,使用完後,程序必須負責相應的調用free或delete釋放該內存塊,否則,這塊內存就不能被再次使用,我們就說這塊內存泄漏了。
㈦ 如何檢測內存泄漏
內存泄漏指由於疏忽或錯誤造成程序未能釋放已經不再使用的內存的情況。內存泄漏並非指內存在物理上的消失,而是應用程序分配某段內存後,由於設計錯誤,失去了對該段內存的控制,因而造成了內存的浪費。
可以使用相應的軟體測試工具對軟體進行檢測。
1. ccmalloc——Linux和Solaris下對C和C++程序的簡單的使用內存泄漏和malloc調試庫。
2. Dmalloc——Debug Malloc Library.
3. Electric
Fence——Linux分發版中由Bruce Perens編寫的malloc()調試庫。
4. Leaky——Linux下檢測內存泄漏的程序。
5. LeakTracer——Linux、Solaris和HP-UX下跟蹤和分析C++程序中的內存泄漏。
6. MEMWATCH——由Johan
Lindh編寫,是一個開放源代碼C語言內存錯誤檢測工具,主要是通過gcc的precessor來進行。
7. Valgrind——Debugging and profiling Linux programs, aiming at
programs written in C and C++.
8. KCachegrind——A visualization tool for the profiling data
generated by Cachegrind and Calltree.
9. Leak
Monitor——一個Firefox擴展,能找出跟Firefox相關的泄漏類型。
10. IE Leak Detector
(Drip/IE Sieve)——Drip和IE Sieve leak
detectors幫助網頁開發員提升動態網頁性能通過報告可避免的因為IE局限的內存泄漏。
11. Windows Leaks
Detector——探測任何Win32應用程序中的任何資源泄漏(內存,句柄等),基於Win API調用鉤子。
12. SAP Memory
Analyzer——是一款開源的JAVA內存分析軟體,可用於輔助查找JAVA程序的內存泄漏,能容易找到大塊內存並驗證誰在一直佔用它,它是基於Eclipse
RCP(Rich Client Platform),可以下載RCP的獨立版本或者Eclipse的插件。
13. DTrace——即動態跟蹤Dynamic
Tracing,是一款開源軟體,能在Unix類似平台運行,用戶能夠動態檢測操作系統內核和用戶進程,以更精確地掌握系統的資源使用狀況,提高系統性能,減少支持成本,並進行有效的調節。
14. IBM Rational PurifyPlus——幫助開發人員查明C/C++、託管。NET、Java和VB6代碼中的性能和可靠性錯誤。PurifyPlus
將內存錯誤和泄漏檢測、應用程序性能描述、代碼覆蓋分析等功能組合在一個單一、完整的工具包中。
15. Parasoft Insure++——針對C/C++應用的運行時錯誤自動檢測工具,它能夠自動監測C/C++程序,發現其中存在著的內存破壞、內存泄漏、指針錯誤和I/O等錯誤。並通過使用一系列獨特的技術(SCI技術和變異測試等),徹底的檢查和測試我們的代碼,精確定位錯誤的准確位置並給出詳細的診斷信息。能作為Microsoft
Visual C++的一個插件運行。
16. Compuware DevPartner for Visual C++ BoundsChecker
Suite——為C++開發者設計的運行錯誤檢測和調試工具軟體。作為Microsoft Visual Studio和C++ 6.0的一個插件運行。
17. Electric Software GlowCode——包括內存泄漏檢查,code
profiler,函數調用跟蹤等功能。給C++和。Net開發者提供完整的錯誤診斷,和運行時性能分析工具包。
18. Compuware DevPartner Java
Edition——包含Java內存檢測,代碼覆蓋率測試,代碼性能測試,線程死鎖,分布式應用等幾大功能模塊。
19. Quest JProbe——分析Java的內存泄漏。
20. ej-technologies JProfiler——一個全功能的Java剖析工具,專用於分析J2SE和J2EE應用程序。它把CPU、執行緒和內存的剖析組合在一個強大的應用中。JProfiler可提供許多IDE整合和應用伺服器整合用途。JProfiler直覺式的GUI讓你可以找到效能瓶頸、抓出內存泄漏、並解決執行緒的問題。4.3.2注冊碼:A-G666#76114F-1olm9mv1i5uuly#0126
21. BEA JRockit——用來診斷Java內存泄漏並指出根本原因,專門針對Intel平台並得到優化,能在Intel硬體上獲得最高的性能。
22. SciTech Software AB .NET Memory
Profiler——找到內存泄漏並優化內存使用針對C#,VB.Net,或其它。Net程序。
23. YourKit .NET & Java Profiler——業界領先的Java和。NET程序性能分析工具。
24. AutomatedQA AQTime——AutomatedQA的獲獎產品performance profiling和memory
debugging工具集的下一代替換產品,支持Microsoft, Borland, Intel, Compaq 和
GNU編譯器。可以為。NET和Windows程序生成全面細致的報告,從而幫助您輕松隔離並排除代碼中含有的性能問題和內存/資源泄露問題。支持。Net
1.0,1.1,2.0,3.0和Windows 32/64位應用程序。
25. JavaScript Memory Leak Detector——微軟全球產品開發歐洲團隊(Global Proct
Development- Europe team, GPDE)
發布的一款調試工具,用來探測JavaScript代碼中的內存泄漏,運行為IE系列的一個插件。
㈧ 什麼是內存泄露內存泄露如何解決
1、內存泄漏指由於疏忽或錯誤造成程序未能釋放已經不再使用的內存的情況。
2、一般我們常說的內存泄漏是指堆內存的泄漏。堆內存是指程序從堆中分配的,大小任意的,
使用完後必須顯式釋放的內存。應用程序一般使用malloc,calloc,realloc,new等函數從堆
中分配到一塊內存,使用完後,程序必須負責相應的調用free或delete釋放該內存塊,否則
這塊內存就不能被再次使用,就是這塊內存泄漏了。
3、內存泄露多數屬於程序本身設計問題,有以下幾種解決方法:
1)從程序內部重新編譯。養成良好的編碼習慣,盡量在涉及內存的程序段,檢測出內存泄露。
2)結束程序,內存自然就會被操作系統回收。
3)重新啟動電腦後,立刻恢復。
㈨ 內存溢出和內存泄漏
內存溢出 out of memory,是指程序在申請內存時,沒有足夠的內存空間供其使用,出現out of memory;比如申請了一個integer,但給它存了long才能存下的數,那就是內存溢出。
內存泄露 memory leak,是指程序在申請內存後,無法釋放已申請的內存空間,一次內存泄露危害可以忽略,但內存泄露堆積後果很嚴重,無論多少內存,遲早會被佔光。
memory leak會最終會導致out of memory!
一,常見的內存溢出情況:
1,載入圖片過大,超出所申請的內存
解決方法:
(1)對圖片進行壓縮處理(不推薦,圖片多起來,你再怎麼壓縮也是要耗很大的內存)
(2)使用第三方載入圖片框架(推薦,開源,省時又省事)Glide ,Picasso ,Fresco等
(3)減少Bitmap對象的引用,並及時的回收
2,對象引用沒及時回收,導致堆積,超出所申請的內存
解決方法:
(1)動態回收內存
(2)對像引用採用軟引用(方便內能夠對此進行回收)
(3)對象復用,存在的對象不要重復多次new它,應該循環利用
(4)注意對象復用的生命周期(static和程序進程一樣長)
(5)單例模式的合理使用,單例模式避免重復創建對象,但也注意他的生命周期和程序進程一樣長容易因為持有的對象沒有正常回收導致內存泄漏
(6)監聽器不使用時及時注銷
(7)盡量減少抽象對象的使用
3,頁面持有內存,沒有及時回收
(1)Activity,fragment頁面:
(2)webview頁面
4,無用服務後台持續運作,佔用過多內存
(1)用完及時關閉
二,常見的內存泄漏情況:
1,Handler 引發內存泄漏
(1)handler發送的Message未被處理,那麼該Message及發送它的Handler對象都會被線程一直持有,由於Handler屬於TLS(Thread Local Storage)變數,生命周期和Activity是不一致的。如果Handler是我們的Activity類的非靜態內部類,Handler就會持有Acitvity的強引用,此時該Activity退出時無法進行內存回收,造成內存泄漏。
解決方法:
將Handler聲明為靜態內部類和軟引用,這樣它就不會持有外部類的引用了,Handler的生命周期就與Activity無關了。聲明時context採用Application的Context,銷毀Acitvity時處理掉隊列中的消息。
2,單例模式引發內存泄漏
(1)單例模式的靜態屬性,使它的生命周期和應用一樣長,如果讓單例引用Activity的強引用,Activity無法gc,就會導致內存泄漏。
解決方法:
所以在創建單例時,構造函數里對Activity 的context引用換成 ApplicationContext
3,匿名內部類引起內存泄漏
(1)activity ,fragment 或者view中使用匿名類,匿名類對象會持有Activity,Fragment,View的引用,如果引用傳到非同步線程中,非同步線程和Activityt生命周期不一致的時候,就會造成Activity的泄漏。
解決方法:能直接聲明內部類引用就減少匿名內部類的引用。盡量不把匿名內部類用到非同步線程中去
4,WebView 引起的內存泄漏
(1)webview解析網頁時會申請Natvie堆內存用於保存頁面元素,當頁面較復雜時,會有很大的內存佔用。如果包含圖片,內存佔用會更嚴重,並且打開新頁面時,為了能快速回退,之前頁面內存也不會釋放。或者是退出Activity頁面時,webview還在處理網路數據,持有Activity的引用時會導致Activity不能被Gc也會造成內存泄漏。
解決方法:
webview採用動態添加,onDestroy時移除,和銷毀webview。
5,集合引發的內存泄漏
(1)把對象的引用加入集合容器中,當我們不再需要該對象時,並沒有把它的引用從集合中清理掉,當集合中的內容過大的時候,並且是static的時候就造成了內存泄漏。
解決方法:
在onDestory中清空;
6,其他引發內存泄漏
(1)構造Adapter時,沒有使用緩存的convertView
(2)Bitmap在不使用的時候沒有使用recycle()釋放內存
(3)線程未終止造成內存泄漏
(4)對象的注冊與反注冊沒有成對出現造成的內存泄漏;比如注冊廣播接收器,注冊觀察者等
(5)不要在執行頻率很高的方法或者循環中創建對象。
本文整理自以下兩篇文章
原文鏈接: https://blog.csdn.net/lililijunwhy/article/details/87966337
原文鏈接: https://blog.csdn.net/sasafeng/article/details/8559992
㈩ windows 怎麼檢查內存泄漏
Windows
內存診斷程序可以診斷內存泄漏,它會測試計算機隨機存取內存(RAM)是否存在錯誤,包括一組綜合性的內存測試。Windows
內存診斷程序容易使用並且速度快,如果運行
Windows
遇到了問題,可以使用此診斷程序查清問題是否由損壞的硬體所導致的。
還有一個很簡單的辦法來檢查一個程序是否有內存泄漏。就是是用Windows的任務管理器(Task
Manager)。運行程序,然後在任務管理器裡面查看
「內存使用」和」虛擬內存大小」兩項,當程序請求了它所需要的內存之後,如果虛擬內存還是持續的增長的話,就說明了這個程序有內存泄漏問題。
當然如果內存泄漏的數目非常的小,用這種方法可能要過很長時間才能看的出來。