當前位置:首頁 » 編程軟體 » 哪些編譯器不用考慮內存泄露

哪些編譯器不用考慮內存泄露

發布時間: 2022-12-19 15:39:25

❶ vc中處理內存泄露問題

發生內存錯誤是件非常麻煩的事情。編譯器不能自動發現這些錯誤,通常是在程序運行時才能捕捉到。而這些錯誤大多沒有明顯的症狀,時隱時現,增加了改錯的難度。有時用戶怒氣沖沖地把你找來,程序卻沒有發生任何問題,你一走,錯誤又發作了。 常見的內存錯誤及其對策如下:

* 內存分配未成功,卻使用了它。

編程新手常犯這種錯誤,因為他們沒有意識到內存分配會不成功。常用解決辦法是,在使用內存之前檢查指針是否為NULL。如果指針p是函數的參數,那麼在函數的入口處用assert(p!=NULL)進行

檢查。如果是用malloc或new來申請內存,應該用if(p==NULL) 或if(p!=NULL)進行防錯處理。

* 內存分配雖然成功,但是尚未初始化就引用它。

犯這種錯誤主要有兩個起因:一是沒有初始化的觀念;二是誤以為內存的預設初值全為零,導致引用初值錯誤(例如數組)。 內存的預設初值究竟是什麼並沒有統一的標准,盡管有些時候為零值,我們寧可信其無不可信其有。所以無論用何種方式創建數組,都別忘了賦初值,即便是賦零值也不可省略,不要嫌麻煩。

* 內存分配成功並且已經初始化,但操作越過了內存的邊界。

例如在使用數組時經常發生下標「多1」或者「少1」的操作。特別是在for循環語句中,循環次數很容易搞錯,導致數組操作越界。

* 忘記了釋放內存,造成內存泄露。

含有這種錯誤的函數每被調用一次就丟失一塊內存。剛開始時系統的內存充足,你看不到錯誤。終有一次程序突然死掉,系統出現提示:內存耗盡。

動態內存的申請與釋放必須配對,程序中malloc與free的使用次數一定要相同,否則肯定有錯誤(new/delete同理)。

* 釋放了內存卻繼續使用它。

有三種情況:

(1)程序中的對象調用關系過於復雜,實在難以搞清楚某個對象究竟是否已經釋放了內存,此時應該重新設計數據結構,從根本上解決對象管理的混亂局面。

(2)函數的return語句寫錯了,注意不要返回指向「棧內存」的「指針」或者「引用」,因為該內存在函數體結束時被自動銷毀。

(3)使用free或delete釋放了內存後,沒有將指針設置為NULL。導致產生「野指針」。

【規則1】用malloc或new申請內存之後,應該立即檢查指針值是否為NULL。防止使用指針值為NULL的內存。

【規則2】不要忘記為數組和動態內存賦初值。防止將未被初始化的內存作為右值使用。

【規則3】避免數組或指針的下標越界,特別要當心發生「多1」或者「少1」操作。

【規則4】動態內存的申請與釋放必須配對,防止內存泄漏。

【規則5】用free或delete釋放了內存之後,立即將指針設置為NULL,防止產生「野指針」。

❷ 為什麼使用handler.callback內存泄漏

內存泄露的問題其困難在於

1.編譯器不能發現這些問題。
2.運行時才能捕獲到這些錯誤,這些錯誤沒有明顯的症狀,時隱時現。
3.對於手機等終端開發用戶來說,尤為困難。下面從三個方面來解決內存泄露:

對於這類問題,需要有良好的編碼習慣,盡量在涉及內存的程序段,檢測出內存泄露。當程式穩定之後,在來檢測內存泄露時,無疑增加了排除的困難和復雜度。

使用了內存分配的函數,要記得要使用其想用的函數釋放掉,一旦使用完畢。

Heap memory:

malloc\realloc ------ free

new \new[] ---------- delete \delete[]

GlobalAlloc------------GlobalFree

要特別注意數組對象的內存泄漏

MyPointEX *pointArray =new MyPointEX [100];

其刪除形式為:

delete []pointArray

Resource Leak :對於系統資源使用之前要仔細看起使用方法,防止錯誤使用或者忘記釋放掉系統資源。

❸ Objective-C 的 ARC 有什麼缺點,是否能完全避免內存泄露

用arc和非arc混編,非arc的類在arc里實例化並且使用,在arc里居然出現內存泄露,而且應為是arc,所以無法使用release,autorelease和dealloc去管理內存,大俠們有遇到這個問題嗎?請問有什麼解決方案嗎?
應該是不會出現你這種情況的,某一個類若是ARC,則在這個類裡面都應該遵循ARC的用法,而無需關心用到的類是否是ARC的,同樣,在非ARC類裡面,就需要遵循內存管理原則。
用ARC,只是編譯器幫你管理了何時去release,retain,不用ARC就需要你自己去管理,說到底只是誰去管理的問題,所以你再好好看看,可能問題與ARC無關。
如果實在找不到問題,建議你找到泄露的那個對象,將其賦值為nil,因為ARC裡面,一旦對象沒有指針指向,就會馬上被釋放

❹ 有沒有編譯C語言的編譯器,占內存小點的

我只用了VC TC的mingw
你說占很少的內存,系統內存運行時佔用小?兼容GCC推薦的mingw,並沒有圖形界面,佔用內存幾乎可以忽略不計

如果硬碟總空間小,與TC
不使用的其他不知道如何

❺ 如何找到內存泄漏在.NET應用程序的原因

.net應用程序內存原理是由GC進行分代控制的。新生代(0代),年輕代(1)與老年代(2)會在GC不同的時間進行回收,所以基本上不用考慮內存泄露的問題。
但GC回收畢竟通過系統回收的,內存泄露也在所難免——往往泄露的原因是使用了系統資源而沒有正確回收所導致的。比如寫文件時程序突然崩潰,GC未參於回收等原因,部分系統資源需要顯式回收(使用終結器或Disposable介面),而這類似的情況都會造成內存的泄露(電顯式回收是說明使用的資源沒有經過GC回收器所以要顯式回收)。
所以在net編程時防止內存泄露的,對於非托資源的調用時要注意顯式回收(寫終結器或disposable介面),對於託管資源盡量使用using(已經實現IDisposable介面),防止系統崩潰或無法正常回收資源。
還有一種特殊的情況,它其實已經算是非托資源的一種,就是多線程編程時的線程回收,這個一旦不注意就會出現線程沒有正確回收而導致內存泄露。所以對於多線程不熟悉的盡量不要使用底層多線程編程,進行使用線程池或TPL實現。
對於資源未回收導致內存的泄露,本身內容已經超出了.net軟體運行的環境,所以對於直接查詢來說,需要使用第三方工具(內存泄露查詢工具等)本身上對其是無監控的,所以多從代碼上分析,除此之外別無他法(根本沒有任何途徑能告訴是哪行或哪個成員引發的,反過來想想如何能知道是哪行代碼引發的,那麼GC不直接注意到這行代碼在崩潰前直接回收其資源不就可以了)。
所以基本上來說,第五代語言都無法確實什麼情況或原因下引了內存泄露,如果編譯器或運行JIT能找出的話(不用找出蛛絲馬跡),它完全有能力保證不會泄露了。之所以泄露還是他無法監控,超出了該編程譯或JIT的能力范圍了。所以只能從第三方(直接輔助查詢應用程序開辟的內存空間進行記錄)來標識內存泄露,也只是標識內存泄露及處理泄露問題,但對於原因它也是無能為力的。

❻ 解讀在Activity中使用Handler的內存泄漏問題

在開發過程中,我們經常會遇到這樣一種情況,當在Activity中使用handler時,直接創建匿名內部類,會得到一個警告,意思是可能出現內存泄漏,推薦使用靜態內部類。這也是面試時經常被問的一個問題,現在,我們就來解讀一下為什麼會出現這個警告,以及如何改進。

我們知道,Handler在使用時,通過post或者send的方式,可以把消息發送到MessageQueue隊列中,期間Looper循環取出消息去交給對應的handler所在的線程去處理,有些消息還加上了延時發送,這些原因就可能會導致一個問題:當Activity銷毀了,而主線程中一直運行的Looper會持有handler的引用,而我們在創建handler的時候用的是非靜態匿名內部類,所以此handler會持有Activity的引用,導致Activity不會被回收,出現了內存泄漏。因此,編譯器才會給我們一個這樣的警告。

可能有些朋友會疑惑為什麼Looper會持有handler的引用,這就要看源碼了:

不管我們調用post還是send方式發送消息,最終調用的都是sendMessageAtTime方法,而在這個方法中最後調用了enqueueMessage方法,我們來看一下Handler中enqueueMessage的源碼:

可以看到msg.target被賦值給本類對象,也就是我們在activity中創建的handler。也就是說我們在發送Message時,這個消息就把handler給封裝進了自己的內部,只要Message對象不被銷毀,此handler對象就會一直存在,而此Message會一直存儲在MessageQueue消息隊列中,直到Looper取出交給handler處理。可以看到Looper的loop()方法的源碼如下:

交給handler處理完後會回收該消息:

這樣Looper才能斷開與Handler對象的引用,直到這個時候,外部的Activity才可能被回收。因此,在使用handler的時候,不建議再這么使用了。

那麼我們該怎樣正確的使用呢?

可以將Handler聲明為Activity里的一個靜態內部類,內部創建一個WeakReference,將Activity實例用弱引用存起來,這樣就可以了。如果為了方便復用,也可以將Handler單獨提出來作為一個類,原理相同。如下:

採用靜態內部類或者單獨提出來的作用是讓handler對象不再持有activity對象的引用,而對外部activity的使用都是採用弱引用的方式,當垃圾回收器發現此activity只有弱引用時,就會回收它,這樣就不會導致內存泄漏了。

好了,這個問題就解讀到這里。下面我們再來看看一些相關的題外知識。

我們平常在使用Looper的時候,必須先調用Looper.prepare()方法,因為此方法會初始化一個Looper(並初始化一個MessageQueue)並和當前線程綁定,只有這些初始化工作完成後,後邊我們才能使用這些東西;然後需要調用Looper.loop()把MessageQueue消息隊列在這個線程中運行起來。下面是prepare方法和創建looper實例的源碼,其中sThreadLocal.set(new Looper(quitAllowed)實現了當前線程和looper的綁定。

但是平時我們在Activity中使用時,並未先調用prepare然後調用loop方法,為什麼呢?我們來看看ActivityThread的main方法,此方法是應用程序的入口,源碼如下:

根據源碼得出,原來APP在啟動的時候,系統已經自動為我們做了相關的初始化工作,這里的ActivityThread就是主線程(UI線程),這樣我們在Activity中就可以直接創建handler使用了。當然我們也可以創建自己的Looper,下面我們來演示子線程中的Handler和主線程中的Handler的使用。

老樣子,我們使用靜態內部類,提供兩個構造函數,無參的給主線程創建handler,有參數的給子線程用,只需提供一個在子線程中初始化的Loope即可。在handleMessage回調方法里列印出當前線程。

然後在主線程和子線程中分別創建各自的實例:

然後在另外一個子線程中使用兩個handler發送消息:

可以看到列印的日誌:

由此可以看出不管handler是在哪個線程中使用,發送的消息都會存儲在創建此handler時對應的Looper所屬的線程中(MessageQueue中),並最後交給這個handler的handleMessage方法進行處理,這樣實現了線程之間的通信。

最後總結:

1.在Activity中直接使用非靜態內部類的Handler,提示會出現內存泄漏,因為非靜態內部類對象會持有外部類對象的引用,如果此內部對象一直被引用著,就會導致外部類對象不會被回收。要麼聲明為靜態,要麼提出去單獨作為一個文件類。並對Activity採用弱引用的方式來使用。

2.應用程序在啟動階段已經替我們做了Looper的初始化工作,我們在Activity中可以直接使用Handler。但是如果想在子線程中創建handler,必須先調用Looper.prepare()方法,然後調用Looper.loop(),這樣才能使用handler。

3.線程--Looper--MessqgeQueue是一一對應的,由msg.target可以得出一個線程中可以創建多個handler,handler的使用(發送消息)可以在任何線程中,但是消息最終都是在創建此handler時對應的Looper所屬線程中被處理的。這樣也就實現了線程間通信。

❼ FreeLibrary內存泄露問題

兩種可能:
1。DLL本身就有內存泄露的bug,只是用demo測試時用的是release版本,這樣內存泄露了也不會報錯,只有調試版本才會報錯
2。測試demo中的某處調用了釋放內存的函數,而新工程中沒有這個調用。

跟對話框還是多文檔沒關系。肯定是DLL的實現不好,有的異常情況沒有考慮到,泄露了內存。
你可以再仔細檢查一下DLL中申請釋放內存的地方.

java防止內存的泄漏什麼意思,內存還能泄露

盡管java虛擬機和垃圾回收機制管理著大部分的內存事務,但是在java軟體中還是可能存在內存泄漏的情況。的確,在大型工程中,內存泄漏是一個普遍問題。避免內存泄漏的第一步,就是要了解他們發生的原因。這篇文章就是要介紹一些常見的缺陷,然後提供一些非常好的實踐例子來指導你寫出沒有內存泄漏的代碼。一旦你的程序存在內存泄漏,要查明代碼中引起泄漏的原因是很困難的。同時這篇文章也要介紹一個新的工具來查找內存泄漏,然後指明發生的根本原因。這個工具容易上手,可以讓你找到產品級系統中的內存泄漏。

垃圾回收(GC)的角色

雖然垃圾回收關心著大部分的問題,包括內存管理,使得程序員的任務顯得更加輕松,但是程序員還是可能犯些錯誤導致內存泄漏問題。GC(垃圾回收)通過遞歸對所有從「根」對象(堆棧中的對象,靜態數據成員,JNI句柄等等)繼承下來的引用進行工作,然後標記所有可以訪問的活動著的對象。而這些對象變成了程序唯一能夠操縱的對象,其他的對象都被釋放了。因為GC使得程序不能夠訪問那些被釋放的對象,所以這樣做是安全的。

內存管理可以說是自動的,但是這並沒有讓程序員脫離內存管理問題。比方說,對於內存的分配(還有釋放)總是存在一定的開銷,盡管這些開銷對程序員來說是隱含的。一個程序如果創建了很多對象,那麼它就要比完成相同任務而創建了較少對象的程序執行的速度慢(如果其他的條件都相同)。

文章更多想說的,導致內存泄漏主要的原因是,先前申請了內存空間而忘記了釋放。如果程序中存在對無用對象的引用,那麼這些對象就會駐留內存,消耗內存,因為無法讓垃圾回收器驗證這些對象是否不再需要。正如我們前面看到的,如果存在對象的引用,這個對象就被定義為「活動的」,同時不會被釋放。要確定對象所佔內存將被回收,程序員就要務必確認該對象不再會被使用。典型的做法就是把對象數據成員設為null或者從集合中移除該對象。注意,當局部變數不需要時,不需明顯的設為null,因為一個方法執行完畢時,這些引用會自動被清理。

從更高一個層次看,這就是所有存在內存管的語言對內存泄漏所考慮的事情,剩餘的對象引用將不再會被使用。

典型的泄漏

既然我們知道了在java中確實會存在內存泄漏,那麼就讓我們看一些典型的泄漏,並找出他們發生的原因。

全局集合

在大型應用程序中存在各種各樣的全局數據倉庫是很普遍的,比如一個JNDI-tree或者一個session table。在這些情況下,注意力就被放在了管理數據倉庫的大小上。當然是有一些適當的機制可以將倉庫中的無用數據移除。

可以有很多不同的解決形式,其中最常用的是一種周期運行的清除作業。這個作業會驗證倉庫中的數據然後清除一切不需要的數據。

另一個辦法是計算引用的數量。集合負責跟蹤集合中每個元素的引用者數量。這要求引用者通知集合什麼時候已經對元素處理完畢。當引用者的數目為零時,就可以移除集合中的相關元素。

高速緩存

高速緩存是一種用來快速查找已經執行過的操作結果的數據結構。因此,如果一個操作執行很慢的話,你可以先把普通輸入的數據放入高速緩存,然後過些時間再調用高速緩存中的數據。

高速緩存多少還有一點動態實現的意思,當數據操作完畢,又被送入高速緩存。一個典型的演算法如下所示:

1. 檢查結果是否在高速緩存中,存在則返回結果;

2. 如果結果不在,那麼計算結果;

3. 將結果放入高速緩存,以備將來的操作調用。

這個演算法的問題(或者說潛在的內存泄漏)在最後一步。如果操作是分別多次輸入,那麼存入高速緩存的內容將會非常大。很明顯這個方法不可取。

為了避免這種潛在的致命錯誤設計,程序就必須確定高速緩存在他所使用的內存中有一個上界。因此,更好的演算法是:

1. 檢查結果是否在高速緩存中,存在則返回結果;

2. 如果結果不在,那麼計算結果;

3. 如果高速緩存所佔空間過大,移除緩存中舊的結果;

4. 將結果放入高速緩存,以備將來的操作調用。

通過不斷的從緩存中移除舊的結果,我們可以假設,將來,最新輸入的數據可能被重用的幾率要遠遠大於舊的結果。這通常是一個不錯的設想。

這個新的演算法會確保高速緩存的容量在預先確定的范圍內。精確的范圍是很難計算的,因為緩存中的對象存在引用時將繼續有效。正確的劃分高速緩存的大小是一個復雜的任務,你必須權衡可使用內存大小和數據快速存取之間的矛盾。

另一個解決這個問題的途徑是使用java.lang.ref.SoftReference類來將對象放入高速緩存。這個方法可以保證當虛擬機用完內存或者需要更多堆的時候,可以釋放這些對象的引用。

類裝載器

Java類裝載器創建就存在很多導致內存泄漏的漏洞。由於類裝載器的復雜結構,使得很難得到內存泄漏的透視圖。這些困難不僅僅是由於類裝載器只與「普通的」對象引用有關,同時也和對象內部的引用有關,比如數據變數,方法和各種類。這意味著只要存在對數據變數,方法,各種類和對象的類裝載器,那麼類裝載器將駐留在JVM中。既然類裝載器可以同很多的類關聯,同時也可以和靜態數據變數關聯,那麼相當多的內存就可能發生泄漏。

定位內存泄漏

常常地,程序內存泄漏的最初跡象發生在出錯之後,在你的程序中得到一個OutOfMemoryError。這種典型的情況發生在產品環境中,而在那裡,你希望內存泄漏盡可能的少,調試的可能性也達到最小。也許你的測試環境和產品的系統環境不盡相同,導致泄露的只會在產品中暴露。這種情況下,你需要一個低負荷的工具來監聽和尋找內存泄漏。同時,你還需要把這個工具同你的系統聯系起來,而不需要重新啟動他或者機械化你的代碼。也許更重要的是,當你做分析的時候,你需要能夠同工具分離而使得系統不會受到干擾。

一個OutOfMemoryError常常是內存泄漏的一個標志,有可能應用程序的確用了太多的內存;這個時候,你既不能增加JVM的堆的數量,也不能改變你的程序而使得他減少內存使用。但是,在大多數情況下,一個OutOfMemoryError是內存泄漏的標志。一個解決辦法就是繼續監聽GC的活動,看看隨時間的流逝,內存使用量是否會增加,如果有,程序中一定存在內存泄漏。

詳細輸出

有很多辦法來監聽垃圾回收器的活動。也許運用最廣泛的就是以:-Xverbose:gc選項運行JVM,然後觀察輸出結果一段時間。

[memory] 10.109-10.235: GC 65536K->16788K (65536K), 126.000 ms

箭頭後的值(在這個例子中 16788K)是垃圾回收後堆的使用量。

控制台

觀察這些無盡的GC詳細統計輸出是一件非常單調乏味的事情。好在有一些工具來代替我們做這些事情。The JRockit Management Console可以用圖形的方式輸出堆的使用量。通過觀察圖像,我們可以很方便的觀察堆的使用量是否伴隨時間增長。

Figure 1. The JRockit Management Console

管理控制台甚至可以配置成在堆使用量出現問題(或者其他的事件發生)時向你發送郵件。這個顯然使得監控內存泄漏更加容易。

內存泄漏探測工具

有很多專門的內存泄漏探測工具。其中The JRockit Memory Leak Detector可以供來觀察內存泄漏也可以針對性地找到泄漏的原因。這個強大的工具被緊密地集成在JRockit JVM中,可以提供最低可能的內存事務也可以輕松的訪問虛擬機的堆。

專門工具的優勢

一旦你知道程序中存在內存泄漏,你需要更專業的工具來查明為什麼這里會有泄漏。而JVM是不可能告訴你的。現在有很多工具可以利用了。這些工具本質上主要通過兩種方法來得到JVM的存儲系統信息的:JVMTI和位元組碼儀器。Java虛擬機工具介面(JVMTI)和他的原有形式JVMPI(壓型介面,profiling Interface)都是標准介面,作為外部工具同JVM進行通信,搜集JVM的信息。位元組碼儀器則是引用通過探針獲得工具所需的位元組信息的預處理技術。

通過這些技術來偵測內存泄漏存在兩個缺點,而這使得他們在產品級環境中的運用不夠理想。首先,根據兩者對內存的使用量和內存事務性能的降級是不可以忽略的。從JVM獲得的堆的使用量信息需要在工具中導出,收集和處理。這意味著要分配內存。按照JVM的性能導出信息是需要開銷的,垃圾回收器在搜集信息的時候是運行的非常緩慢的。另一個缺點就是,這些工具所需要的信息是關繫到JVM的。讓工具在JVM開始運行的時候和它關聯,而在分析的時候,分離工具而保持JVM運行,這顯然是不可能的。

既然JRockit Memory Leak Detector是被集成到JVM中的,那麼以上兩種缺點就不再存在。首先,大部分的處理和分析都是在JVM中完成的,所以就不再需要傳送或重建任何數據。處理也可以建立在垃圾回收器的基礎上,即提高速度。再有,內存泄漏偵測器可以同一個運行的JVM關聯和分離,只要JVM在開始的時候伴隨著 –Xmanagement選項(通過遠程JMX介面允許監聽和管理JVM)。當工具分離以後,工具不會遺留任何東西在JVM中;JVM就可以全速運行代碼就好像工具關聯之前一樣。

趨勢分析

讓我們更深一步來觀察這個工具,了解他如何捕捉到內存泄漏。在你了解到代碼中存在內存泄漏,第一步就是嘗試計算出什麼數據在泄漏——哪個對象類導致泄露。The JRockit Memory Leak Detector通過在垃圾回收的時候,計算每個類所包含的現有的對象來達到目的。如果某一個類的對象成員數目隨著時間增長(增長率),那麼這里很可能存在泄漏。

Figure 2. The trend analysis view of the Memory Leak Detector

因為一個泄漏很可能只是像水滴一樣小,所以趨勢分析必須運行足夠長的一段時間。在每個短暫的時間段里,局部類的增加會使得泄漏發生推遲。但是,內存事務是非常小的(最大的內存事務是由在每個垃圾回收時從JRockit向內存泄漏探測器發送的一個數據包組成的)。內存事務不應該成為任何系統的問題——甚至一個在產品階段全速運行的程序。

一開始,數字會有很大的跳轉,隨時間的推進,這些數字會變得穩定,而後顯示哪些類會不斷的增大。

尋找根本原因

知道那些對象的類會導致泄露,有時候足夠制止泄露問題。這個類也許只是被用在非常有限的部分,通過快速的視察就可以找到問題所在。不幸的是,這些信息是不夠的。比方說,經常導致內存泄漏的對象類java.lang.String,然而String類被應用於整個程序,這就變得有些無助。

我們想知道的是其他的對象是否會導致內存泄漏,好比上面提到的String類,為什麼這些導致泄漏的對象還是在周圍存在?哪些引用是指向這些對象的?如果列出所有引用String的對象,工作就會變得太大而沒有實際意義。為了限制數據的數量,我們可以通過類把他們編成一個組,這樣我們就可以看到,那些其他類的對象會依然泄漏對象(String類)。比如,將一個String類放入Hashtable,那裡我們可以看到關聯到String類的Hashtable入口。從Hashtable入口向後運行,我們終於找到那些關聯到String類的Hashtable對象(參看圖三如下)。

Figure 3. Sample view of the type graph as seen in the tool

向後工作

自從開始我們就一直著眼於對象類,而不是單獨的對象,我們不知道那個Hashtable存在泄漏。如果我們可以找出所有的Hashtable在系統中有多大,我們可以假設最大的那個Hashtable存在泄漏(因為它可以聚集足夠的泄漏而變得很大)。因此,所有Hashtable,同時有和所有他們所涉及的數據,可以幫助我們查明導致泄露的精確的Hashtable。

Figure 4. Screenshot of the list of Hashtable objects and the size of the data they are holding live

計算一個對象所涉及的數據的開銷是非常大的(這要求引用圖表伴隨著那個對象作為根運行)而且如果對每一個對象都這樣處理,就需要很多時間。知道一些關於Hashtable內部的實現機制可以帶來捷徑。在內部,一個Hashtable有一個Hashtable的數組入口。數組的增長伴隨著Hashtable中對象的增長。因此,要找到最大的Hashtable,我們可以把搜索限制在尋找包含Hashtable引用入口的最大的數組。這樣就更快捷了。

Figure 5. Screenshot of the listing of the largest Hashtable entry arrays, as well as their sizes.

向下深入

當我們發現了存在泄漏的Hashtable的實例,就可以順藤摸瓜找到其他的引用這些Hashtable的實例,然後用上面的方法來找到是那個Hashtable存在問題。

Figure 6. This is what an instance graph can look like in the tool
.

舉個例子,一個Hashtable可以有一個來自MyServer的對象的引用,而MyServer包含一個activeSessions數據成員。這些信息就足夠深入代碼找出問題所在。

Figure 7. Inspecting an object and its references to other objects

找出分配點

當發現了內存泄漏問題,找到那些泄漏的對象在何處是非常有用的。也許沒有足夠的信息知道他們同其他相關對象之間的聯系,但是關於他們在那裡被創建的信息還是很有幫助的。當然,你不會願意創建一個工具來列印出所有分配的堆棧路徑。你也不會願意在模擬環境中運行程序只是為了捕捉到一個內存泄漏。

有了JRockit Memory Leak Detector,程序代碼可以動態的在內存分配出創建堆棧路徑。這些堆棧路徑可以在工具中累積,分析。如果你不啟用這個工具,這個特徵就不會有任何消耗,這就意味著時刻准備著開始。當需要分配路徑時,JRockit的編譯器可以讓代碼不工作,而監視內存分配,但只對需要的特定類有效。更好的是,當做完數據分析後,生成的機械代碼會完全被移除,不會引起任何執行上的效率衰退。

Figure 8. The allocation stack traces for String ring execution of a sample program

總結

內存泄漏查找起來非常困難,文章中的一些避免泄漏的好的實踐,包括了要時刻記住把什麼放進了數據結構中,更接近的監視內存中意外的增長。

我們同時也看到了JRockit Memory Leak Detector是如何捕捉產品級系統中的內存泄漏的。該工具通過三步的方法發現泄漏。一,通過趨勢分析發現那些對象類存在泄漏;二,找出同泄漏對象相關的其他類;三,向下發掘,觀察獨立的對象之間是如何相互聯系的。同時,該工具也可以動態的,找出所有內存分配的堆棧路徑。利用這三個特性,將該工具緊緊地集成在JVM中,那麼就可以安全的,有效的捕捉和修復內存泄漏了。

❾ 內存泄漏編譯器會報錯嗎

不會,而且也會運行成功。內存泄露是指內存分配了但是沒有釋放,如果程序在運行過程中不停的有內存被分配但是沒有釋放,慢慢的內存就會耗光,就會出現問題。一般我們自己編的程序中的內存泄露不會有直接的錯誤表現,因為我們的程序不是一直運行的,程序停掉之後內存會自動被系統回收。

❿ 在Linux中運行的C程序出現內存泄漏現象,怎麼解決

內存泄漏指由於疏忽或錯誤造成程序未能釋放已經不再使用的內存的情況。內存泄漏並非指內存在物理上的消失,而是應用程序分配某段內存後,由於設計錯誤,失去了對該段內存的控制,因而造成了內存的浪費。
可以使用相應的軟體測試工具對軟體進行檢測。
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系列的一個插件。

熱點內容
安卓jj比賽哪個版本有全記牌器 發布:2025-07-14 08:28:27 瀏覽:72
python腳本執行hive 發布:2025-07-14 08:26:24 瀏覽:488
媒體存儲可以刪除嗎 發布:2025-07-14 08:26:13 瀏覽:812
ios網易雲音樂上傳 發布:2025-07-14 08:16:58 瀏覽:392
榮耀8x可以用方舟編譯器嗎 發布:2025-07-14 08:09:49 瀏覽:277
雲伺服器商家怎麼購買 發布:2025-07-14 08:05:34 瀏覽:45
c語言convert函數 發布:2025-07-14 07:56:34 瀏覽:483
sql存儲過程列印 發布:2025-07-14 07:56:26 瀏覽:658
弄伺服器需要什麼語言 發布:2025-07-14 07:54:27 瀏覽:507
金土火的三才配置是什麼意思 發布:2025-07-14 07:51:21 瀏覽:774