『壹』 如何在linux下檢測內存泄漏
要想檢測內存泄漏,就必須對程序中的內存分配和釋放情況進行記錄,所能夠採取的辦法就是重載所有形式的operator new 和 operator delete,截獲 new operator 和 delete operator 執行過程中的內存操作信息。下面列出的就是重載形式
void* operator new( size_t nSize, char* pszFileName, int nLineNum )
void* operator new[]( size_t nSize, char* pszFileName, int nLineNum )
void operator delete( void *ptr )
void operator delete[]( void *ptr )
我們為 operator new 定義了一個新的版本,除了必須的 size_t nSize 參數外,還增加了文件名和行號,這里的文件名和行號就是這次 new operator 操作符被調用時所在的文件名和行號,這個信息將在發現內存泄漏時輸出,以幫助用戶定位泄漏具體位置。對於 operator delete,因為無法為之定義新的版本,我們直接覆蓋了全局的 operator delete 的兩個版本。
在重載的 operator new 函數版本中,我們將調用全局的 operator new 的相應的版本並將相應的 size_t 參數傳入,而後,我們將全局 operator new 返回的指針值以及該次分配所在的文件名和行號信息記錄下來,這里所採用的數據結構是一個 STL 的 map,以指針值為 key 值。當 operator delete 被調用時,如果調用方式正確的話(調用方式不正確的情況將在後面詳細描述),我們就能以傳入的指針值在 map 中找到相應的數據項並將之刪除,而後調用 free 將指針所指向的內存塊釋放。當程序退出的時候,map 中的剩餘的數據項就是我們企圖檢測的內存泄漏信息--已經在堆上分配但是尚未釋放的分配信息。
以上就是內存檢測實現的基本原理,現在還有兩個基本問題沒有解決:
1) 如何取得內存分配代碼所在的文件名和行號,並讓 new operator 將之傳遞給我們重載的 operator new。
2) 我們何時創建用於存儲內存數據的 map 數據結構,如何管理,何時列印內存泄漏信息。
先解決問題1。首先我們可以利用 C 的預編譯宏 __FILE__ 和 __LINE__,這兩個宏將在編譯時在指定位置展開為該文件的文件名和該行的行號。而後我們需要將預設的全局 new operator 替換為我們自定義的能夠傳入文件名和行號的版本,我們在子系統頭文件 MemRecord.h 中定義:
#define DEBUG_NEW new(__FILE__, __LINE__ )
而後在所有需要使用內存檢測的客戶程序的所有的 cpp 文件的開頭加入
#include "MemRecord.h"
#define new DEBUG_NEW
就可以將客戶源文件中的對於全局預設的 new operator 的調用替換為 new (__FILE__,__LINE__) 調用,而該形式的new operator將調用我們的operator new (size_t nSize, char* pszFileName, int nLineNum),其中 nSize 是由 new operator 計算並傳入的,而 new 調用點的文件名和行號是由我們自定義版本的 new operator 傳入的。我們建議在所有用戶自己的源代碼文件中都加入上述宏,如果有的文件中使用內存檢測子系統而有的沒有,則子系統將可能因無法監控整個系統而輸出一些泄漏警告。
再說第二個問題。我們用於管理客戶信息的這個 map 必須在客戶程序第一次調用 new operator 或者 delete operator 之前被創建,而且在最後一個 new operator 和 delete operator 調用之後進行泄漏信息的列印,也就是說它需要先於客戶程序而出生,而在客戶程序退出之後進行分析。能夠包容客戶程序生命周期的確有一人--全局對象(appMemory)。我們可以設計一個類來封裝這個 map 以及這對它的插入刪除操作,然後構造這個類的一個全局對象(appMemory),在全局對象(appMemory)的構造函數中創建並初始化這個數據結構,而在其析構函數中對數據結構中剩餘數據進行分析和輸出。Operator new 中將調用這個全局對象(appMemory)的 insert 介面將指針、文件名、行號、內存塊大小等信息以指針值為 key 記錄到 map 中,在 operator delete 中調用 erase 介面將對應指針值的 map 中的數據項刪除,注意不要忘了對 map 的訪問需要進行互斥同步,因為同一時間可能會有多個線程進行堆上的內存操作。
好啦,內存檢測的基本功能已經具備了。但是不要忘了,我們為了檢測內存泄漏,在全局的 operator new 增加了一層間接性,同時為了保證對數據結構的安全訪問增加了互斥,這些都會降低程序運行的效率。因此我們需要讓用戶能夠方便的 enable 和 disable 這個內存檢測功能,畢竟內存泄漏的檢測應該在程序的調試和測試階段完成。我們可以使用條件編譯的特性,在用戶被檢測文件中使用如下宏定義:
#include "MemRecord.h"
#if defined( MEM_DEBUG )
#define new DEBUG_NEW
#endif
當用戶需要使用內存檢測時,可以使用如下命令對被檢測文件進行編譯
g++ -c -DMEM_DEBUG xxxxxx.cpp
就可以 enable 內存檢測功能,而用戶程序正式發布時,可以去掉 -DMEM_DEBUG 編譯開關來 disable 內存檢測功能,消除內存檢測帶來的效率影響。
『貳』 如何定位分析linux內存泄漏問題
1、閱讀源代碼及分析動態內存的使用
由於之前沒有做過類似的問題(純屬小專白了,慘遭鄙視....),所以就想屬著通過自己去看代碼,查找裡面涉及到使用動態內存的代碼段去定位問題(現在想想,真是太幼稚了,大家見笑了...),但是自己還是去通過對源代碼跟蹤、分析,主要是對動態分配的內存(如malloc函數分配的內存)、一些文件描述符等進行跟蹤,分析在程序邏輯中對動態分配的內存有沒有手動進行釋放,打開的文件描述符有沒有關閉等這些代碼一點點的去分析,當然這也是熟悉代碼,了解的一個過程。
2、利用memwatch內存檢測工具對程序進行內存分析
Memwatch是一款C語言的內存檢測工具。memwatch使用它自己定義的功能函數取代所有在你的程序中用ANSI C定義的內存分配函數,memwatch的內存分配函數包含了所有的分配記錄信息。memwatch功能默認不是開啟的,除非定義了MEMWATCH,否則在代碼中不會跟蹤相關的內存使用情況。memwatch通常將它的數據寫入到memwatch.log文件中,它也可以被重定向.更多Linux操作知識,可以網路《Linux就該這么學》。
『叄』 怎麼樣來檢查Linux系統下內存泄漏
內存泄漏是指程序動態申請的內存在使用完後沒有釋放,導致這段內存不能被操作系統回收再利用。 例如這段程序,申請了4個位元組的空間但沒有釋放,有4個位元組的內存泄漏。
#include <iostream>using namespace std;int main()
{ int *p = new int(1); cout <<*p<<endl; return 0}
1
2
3
4
5
6
7
8
9
隨著時間的推移,泄漏的內存越來越多,可用的內存越來越少,輕則性能受損,重則系統崩潰。
一般情況下,發生內存泄漏時,重啟就可以回收泄漏的內存。但是對於Linux,通常跑的是伺服器程序,不可以隨意重啟,在內存泄漏問題上就要格外小心。
內存泄漏特點
難復現 — 要運行到足夠長的時間才會暴露。
難定位 — 出錯位置是隨機的,看不出與內存泄漏的代碼有什麼聯系。
最簡單的方法
為了避免寫出內存泄漏的程序,通常會有這樣的編程規范,要求我們在寫程序時申請和釋放成對出現的。因為每一次申請都意味著必須有一次釋放與它相對應。
基於這個特點,一種簡單的方法就是在代碼中統計申請和釋放的次數,如果申請和釋放的數量不同,就認為是內存泄漏了。
#include "stdio.h"#include "stdlib.h"int malloc_count, free_count;void * my_malloc(int size)
{
malloc_count++; return malloc(size);
}void my_free(void *p)
{
free_count++; free(p);
}int main()
{
count = 0; int *p1 = (int *)my_malloc(sizeif(int)) int *p2 = (int *)my_malloc(sizeif(int)) printf("%d, %d", p1, p2);
my_free(p1); if(malloc_count != free_count) printf("memory leak!\n"); return 0}
『肆』 怎樣發現內存泄露
一、內存泄漏的檢查方法:
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 將內存錯誤和泄漏檢測、應用程序性能描述、代碼覆蓋分析等功能組合在一個單一、完整的工具包中。
二、內存泄漏的簡單介紹:
內存泄漏也稱作「存儲滲漏」,用動態存儲分配函數動態開辟的空間,在使用完畢後未釋放,結果導致一直占據該內存單元。直到程序結束。(其實說白了就是該內存空間使用完畢之後未回收)即所謂內存泄漏。
內存泄漏形象的比喻是「操作系統可提供給所有進程的存儲空間正在被某個進程榨乾」,最終結果是程序運行時間越長,佔用存儲空間越來越多,最終用盡全部存儲空間,整個系統崩潰。所以「內存泄漏」是從操作系統的角度來看的。這里的存儲空間並不是指物理內存,而是指虛擬內存大小,這個虛擬內存大小取決於磁碟交換區設定的大小。由程序申請的一塊內存,如果沒有任何一個指針指向它,那麼這塊內存就泄漏了。
『伍』 top怎麼查看內存泄露linux
看進程內存佔用情況啊
top -c之後按M
就是按內存佔用由大到小排序
如果內存佔用只有一兩GB或者在設置范圍內,一般就是沒有內存泄露。
『陸』 有沒有基於ARM/linux下面的檢測內存泄漏的工具可用
工具
描述
valgrind 一個強大開源的程序檢測工具
mtrace GNU擴展,用來跟蹤malloc,mtrace為內存分配函數回(malloc,rellaoc,memalign,free)安裝答hook函數
dmalloc 用於檢查C/C++內存泄漏的工具,即是檢查是否存在程序運行結束還沒有釋放的內存,以一個運行庫發布
memwatch 和dmalloc一樣,它能檢測未釋放的內存、同一段內存被釋放多次、位址存取錯誤及不當使用未分配之內存區域
mpatrol 一個跨平台的 C++ 內存泄漏檢測器
dbgmem 也是一個動態庫發布的形式,優點類似dmalloc,但是相比之下,可能特點少了一些
Electric Fence 不僅僅能夠跟蹤malloc()和free(),同時能夠檢查讀訪問以及寫入,能夠准確指出導致錯誤的指令
『柒』 linux內存泄漏怎麼查
內存泄漏指由於疏忽或錯誤造成程序未能釋放已經不再使用的內存的情況。內存泄漏並非指內存在物理上的消失,而是應用程序分配某段內存後,由於設計錯誤,失去了對該段內存的控制,因而造成了內存的浪費。
可以使用相應的軟體測試工具對軟體進行檢測。
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系列的一個插件。
『捌』 嵌入式linux怎麼檢內存泄漏雨
檢測內存泄露主要有以下5種方法:
1、在需要內存泄漏檢查的代碼的開始調用void mtrace(void) (該函數在頭文件mcheck.h中有聲明)。mtrace為malloc等函數安裝hook,用於記錄內存分配信息.在需要內存泄漏檢查的代碼的結束調用void muntrace(void)。
注意: 一般情況下不要調用muntrace, 而讓程序自然結束. 因為可能有些釋放內存代碼要到muntrace之後才運行.
2、用debug模式編譯被檢查代碼(-g或-ggdb)。
3、設置環境變數MALLOC_TRACE為一文件名, 這一文件將存有內存分配信息。
4、運行被檢查程序, 直至結束或muntrace被調用。
5、用mtrace命令解析內存分配Log文件($MALLOC_TRACE)
(mtrace foo $MALLOC_TRACE, where foo is the executible name)
如果有內存泄漏,mtrace會輸出分配泄漏
內存的代碼位置,以及分配數量。