Delphi自動管理的記憶體
Delphi中原子變數,如Integer、Boolean、Record、枚舉等都是在範圍內編譯器自動申請記憶體,出了範圍自動釋放;另外,字串、Variant、動態數組、介面也是由Delphi自動管理。
這些變數都是在棧中儲存的,除了介面。另外,Variant是程式員用函數手工建立的,例如VarArrayCreate;動態數組也是程式員用函數手工建立的,例如SetLength,但這兩種情況都不需要程式員自己釋放。
另外,還有一種變數需要注意,是使用Threadvar聲明的變數,它的範圍是一個線程。這主要用在編寫線程函數時,每一個線程使用一個線程局部儲存。
程式員手工管理的記憶體
指標和對象是需要程式員手工申請和釋放的記憶體。
指標包括PChar、Pointer(無類型指標)、記錄指標、變數指標(指向原子變數)、函數指標(例如回呼函數,分為全域函數和對象方法)。使用New函數來申請記憶體,使用Dispose來釋放指標。另外,GetMem、ReallocMem和FreeMem也是一系列申請、釋放記憶體的函數,可以通過GetMemoryManager和SetMemoryManager函數來讀取和設定Delphi的三個記憶體管理函數。
對象包括TObject和IUnknown兩顆繼承樹繼承下來的子類對象。必須使用構造方法來構造對象。用構造方法(一般是Create,也可以不是,Delphi的編譯器只認constructor的關鍵字)建立的對象,如果你沒有指定擁有者,那麼必須自己手動釋放,即便是指定了擁有者也需要看實際需要在特定的時刻釋放。釋放一般使用Free方法(IUnknown則不需要手工釋放),更好的方法是使用FreeAndNil(在Sysutils.pas單元),它既釋放佔用的記憶體,同時釋放指標本身。
這些變數都是在堆中儲存的。另外一個需要注意的問題是,TList中的指標都需要程式員自己釋放。
註:
1、回呼函數不屬於記憶體管理的技術範疇,詳細內容參見《指標》部分。
2、對象的詳細內容參見《物件模型》部分。
3、一個指標被多個地方使用,而其中一個地方釋放了,其他地方再使用就會發生異常,這是一個使用指標應該注意的問題。詳細記憶體參見《指標》部分。
4、傳遞指標有兩個很明顯的優勢:節省記憶體、提高速度。詳細記憶體參見《指標》和《設計技巧》部分。
5、如何判斷對象和指標是一個技術性很強的主題,csdn上有一些講這個主題的文章,還可以參見Aimingoo(aim@263.net)寫的一篇名為《關於“如何檢測指標是否是對象”的深入探討》的文章。詳細記憶體參見《指標》和《對象》部分。