對於內存泄漏問題的簡單認知

看了不少別人對內存泄漏和內存溢出的講解,也看到不少對別人觀點的辯駁。但可能正是由於看的太多了,總感受有點亂,因此仍是本身總結下好。下面是我對於內存泄漏的粗淺認識。程序員

1、內存泄漏簡介

首先要明確在計算機編程中,內存泄漏並不是是指內存在物理上的消失。而是在應用程序分配了某段內存以後,因爲設計錯誤或是某些不明確的bug,致使應用程序在未釋放該段內存以後就失去了對該段內存的控制,從而形成了內存的浪費。數據庫

一些黑客能經過一段攻擊代碼來攻擊能被公衆訪問的網絡服務器或路由器等,使之產生內存泄漏或內存溢出編程

2、內存泄漏的後果

內存泄漏最直接的表現就是致使計算機或服務器性能下降,可是通常不會立刻引發嚴重的情況。服務器

須要明確的是,內存消耗持續增長不必定代表是內存泄漏,多是有其餘緣由引發的。如程序設計者在設計程序時假設存儲器老是足夠運行特定的工做,而申請不合理的大量存儲器。網絡

這是因爲大多數的現代計算機操做系統都有存儲在RAM芯片中主內存和存儲在次級存儲設備如硬盤中的虛擬內存,內存分配是動態的——每一個進程根據要求得到相應的內存。編程語言

訪問活躍的頁面文件被轉移到主內存以提升訪問速度;反之,訪問不活躍的頁面文件被轉移到次級存儲設備。當一個簡單的進程消耗大量的內存時,它一般佔用愈來愈多的主內存,使其餘程序轉到次級存儲設備,使系統的運行效率大大下降。函數

甚至在有內存泄漏的程序終止後,其餘程序須要至關長的時間才能切換到主內存,恢復原來的運行效率。工具

注意:第一個遭遇內存問題的程序不必定是引發內存泄露的程序,須要通過具體排查來肯定是哪一個程序或進程致使的內存泄漏性能

內存泄漏在如下場景當中會顯得很嚴重:測試

  • 程序運行後就置之不理(好比服務器的後臺任務)
  • 頻繁的分配新內存(好比遊戲運行)
  • 程序停止以後也不會被釋放的內存(例如共享內存)
  • 剩餘內存有限的時候
  • 系統關鍵驅動發生內存泄漏

3、容易引發內存泄露的操做

Java等語言中的垃圾回收機制能有效防止內存泄漏,像在沒有垃圾回收的編程語言,如C和C++中,存儲器泄露是很常見的錯誤(不過這兩種語言有垃圾回收的庫)

——垃圾回收
垃圾回收的設計思想,就是用不一樣級別的「訪問性」來標識存儲器中的對象,存儲器管理器按照釋放級別來優先釋放訪問性較低的對象。
強引用的對象或者間接和一組強引用相關的對象就表示該對象的訪問性較強

雖然說Java有GC,但並非就此安然無恙,穩如老狗了。如下這些這些場景不注意的話,仍是容易形成內存泄漏問題的:

  • 靜態集合類的使用(例如 HashMap、Vector),這些靜態變量的生命週期和應用程序的生命週期一致。 可使用 jdk8 中ConCurrentHashMap類(聽說這個類仍是有內存泄漏的風險,jdk9好像解決了,這個能夠自行去了解)。

  • 監聽器。 釋放對象的時候記得刪除監聽器

  • 各類資源的鏈接沒有釋放關閉(如數據庫鏈接、網絡鏈接等)。

  • 循環中建立大量無用對象

  • 泛用單例模式,在單例模式中持有外部對象的引用

  • 內部類和外部模塊的引用

4、如何減小內存泄漏的發生

筆者的建議以下:
1. 平時養成良好的編程習慣,這是最重要的

2. 尋求測試工具的幫助

3. 注意 事件監聽、回調函數、靜態集合對象這幾個內存泄漏大戶

分享一篇有趣的文章內涵系列 | 30 張令程序員淚流滿面的趣圖

相關文章
相關標籤/搜索