內存泄漏是指程序在運行過程中,由于某些原因導致程序無法釋放已經不再使用的內存,使得這部分內存持續被占用,最終可能導致系統可用內存逐漸減少,嚴重時會影響系統性能甚至導致程序崩潰。(內存泄漏是指程序中已經分配的內存由于各種原因(如對象引用未正確釋放、資源未關閉等),無法被垃圾回收機制回收,而不是真正意義上的 “漏出去”。例如,在 C# 中,如果一個靜態集合類持有了對象的引用,并且在對象不再使用時沒有將其從集合中移除,那么這些對象占用的內存就無法被回收,這就是一種內存泄漏的情況。)
目錄
靜態集合類引起的內存泄漏
未釋放的資源
事件訂閱未取消
內部類持有外部類引用
緩存使用不當
靜態集合類引起的內存泄漏
靜態集合類(如?static List
、static Dictionary
?等)的生命周期與應用程序的生命周期一致。如果將對象添加到靜態集合中,并且在對象不再使用時沒有從集合中移除,這些對象將一直被集合引用,無法被垃圾回收機制回收,從而造成內存泄漏。(解決辦法:在對象不再需要時,主動從靜態集合中移除該對象的引用,這樣垃圾回收器就可以回收該對象占用的內存;使用弱引用的對象,這種對象可以被垃圾回收;使用過期策略的緩存,到了一定時間會自動回收)
未釋放的資源
許多資源(如文件句柄、數據庫連接、網絡連接、圖形設備上下文等)需要手動釋放。如果在使用完這些資源后沒有調用相應的?Dispose
?方法(實現了?IDisposable
?接口的對象)或?Close
?方法來釋放資源,會導致資源一直被占用,造成內存泄漏。更好的做法是使用?using
?語句,它會自動調用?Dispose
?方法。
事件訂閱未取消
當一個對象訂閱了另一個對象的事件時,訂閱對象會持有對發布對象的引用。如果在訂閱對象不再需要接收事件時,沒有取消訂閱,發布對象會一直持有訂閱對象的引用,導致訂閱對象無法被垃圾回收,造成內存泄漏。(為避免內存泄漏,應在合適的時候取消訂閱)
內部類持有外部類引用
在 C# 中,非靜態內部類會隱式持有外部類的引用。如果內部類的生命周期比外部類長,且沒有正確處理這種引用關系,會導致外部類無法被垃圾回收,造成內存泄漏。(可采用使用靜態內部類(使其不隱式持有外部類引用)、手動解除內部類對外部類的引用(在不再需要時將引用置為 null)、使用弱引用(讓內部類對外部類的引用不阻止外部類被回收)等方法。)
緩存使用不當
如果在程序中使用緩存(緩存(Cache)是一種數據存儲機制,它充當數據的臨時存儲區域,位于高速設備(如內存)中,用于減少對低速數據源(如磁盤、網絡數據庫等)的頻繁訪問,以此來提高數據訪問的速度和系統的整體性能。很多情況下字典可以被看作是簡單的緩存)來存儲數據,并且沒有合理的緩存清理策略,隨著緩存數據的不斷增加,會占用大量內存,導致內存泄漏。(可以通過設置緩存項的過期時間或最大容量限制來避免內存泄漏。)