1. 程式人生 > >(整合多篇文章)C++懸垂指標、野指標、記憶體洩漏和垃圾回收機制

(整合多篇文章)C++懸垂指標、野指標、記憶體洩漏和垃圾回收機制

C++的記憶體回收機制

當我們使用new為一個物件分配了空間之後,在這個物件結束使用之後,我們必須人為的去釋放這塊記憶體(delete)

Java的記憶體回收機制

 當用new 建立一個Java物件時,它可以存活於作用域之外。所以在上述程式碼中,引用 str(str為String物件“HelloWorld!” 的引用) 在作用域終點就消失了。然而,str指向的String物件仍繼續佔用記憶體 堆空間 。在這一段程式碼中,我們無法在這個作用域之後訪問這個物件,因為對它唯一的引用已經超出作用域的範圍。(注:如果想使用 我們需要傳遞或者複製這個引用)

事實證明,由new建立的物件,只要你需要,就會一直儲存下去。這樣,許多C++程式設計問題在Java中就會完全消失。在C++中,你不僅需要去確保物件的保留時間與你所需要的這些物件的的時間一樣長,而且必須在使用完之後將其銷燬。

但是,如果Java讓物件繼續存在,那麼靠什麼才能防止這些物件填滿記憶體空間,進而阻塞程式呢? 這正是C++裡可能發生的問題。同時這也是Java的神奇所在。Java是這樣處理的。

在Java 中有一個 垃圾回收器 ,用來監視用new建立的所有物件,並辨別那些不會再被引用的物件。隨後,釋放這些物件的記憶體空間,以便供其他新的物件使用。也就是說,程式設計師們根本不必擔心記憶體回收的問題。只需要建立物件,一旦不需要了,他們就會由垃圾回收器自動回收,記憶體就會自動得到釋放。這樣做就消除了這類程式設計問題(“記憶體洩漏問題”)。

這種解決方法大大簡化了程式設計的難度。

懸垂指標

在許多程式語言中(比如C),顯示地從記憶體中刪除一個物件或者返回時通過銷燬棧幀,並不會改變相關的指標的值。該指標仍舊指向記憶體中相同的位置,即使引用已經被刪除,現在可能已經挪作他用。


如果作業系統能夠偵測執行時的指向空指標的引用,一個方案是在內部快消失之前給dp賦為0(NULL)。另一個方案是保證dp在沒有被初始化之前不再被使用。

另一個常見原因是混用 malloc() 和 free():當一個指標指向的記憶體被釋放後就會變成懸垂指標。正如上個例子,可以避免這個問題的一種方法是在釋放它的引用後把指標重置為NULL。

一個很常見的失誤是返回一個棧分配的區域性變數:一旦呼叫的函式返回了,分配給這些變數的空間被回收,此時它們擁有的是“垃圾值”。

野指標

野指標的產生是由於在首次使用之前沒有進行必要的初始化。因此,嚴格地說,在程式語言中的所有為初始化的指標都是野指標。

在更多結構化的解決方案中,一種流行的避免懸垂指標的技術是使用智慧指標

。一個智慧指標通常使用引用技術來收回物件。還有些技術包括 tombstones 方法和 locks-and-keys 方法。

另一個方法是使用 Boehm 垃圾收集器,一種保守的垃圾收集器,取代C和C++中的標準記憶體分配函式。此法通過禁止記憶體釋放函式來完全消除懸垂指標引發的錯誤,通過收集垃圾來回收物件。

像Java語言,懸垂指標這樣的錯誤是不會發生的,因為Java中沒有明確地重新分配記憶體的機制。而且垃圾回收器只會在物件的引用數為0時重新分配記憶體。


轉載:

http://blog.csdn.net/leo115/article/details/8190077

www.cnblogs.com/submarinex/