一:內存-內存泄漏
程序的運行需要內存。只要程序提出要求养篓,操作系統(tǒng)或者運行時(runtime)就必須供給內存秃流。對于持續(xù)運行的服務進程(daemon),必須及時釋放不再用到的內存柳弄。否則舶胀,內存占用越來越高,輕則影響系統(tǒng)性能碧注,重則導致進程崩潰嚣伐。
不再用到的內存,沒有及時釋放应闯,就叫做內存泄漏(memory leak)纤控。
有些語言(比如 C 語言)必須手動釋放內存,程序員負責內存管理碉纺。
char * buffer;
buffer = (char*) malloc(42);
// Do something with buffer
free(buffer);
上面是 C 語言代碼船万,malloc方法用來申請內存,使用完畢之后骨田,必須自己用free方法釋放內存耿导。
這很麻煩,所以大多數(shù)語言提供自動內存管理态贤,減輕程序員的負擔舱呻,這被稱為"垃圾回收機制"(garbage collector)。
二、垃圾回收機制
垃圾回收機制怎么知道箱吕,哪些內存不再需要呢芥驳?
最常使用的方法叫做"引用計數(shù)"(reference counting):語言引擎有一張"引用表",保存了內存里面所有的資源(通常是各種值)的引用次數(shù)茬高。如果一個值的引用次數(shù)是0兆旬,就表示這個值不再用到了,因此可以將這塊內存釋放怎栽。
上圖中丽猬,左下角的兩個值,沒有任何引用熏瞄,所以可以釋放脚祟。
如果一個值不再需要了,引用數(shù)卻不為0强饮,垃圾回收機制無法釋放這塊內存由桌,從而導致內存泄漏。
const arr = [1, 2, 3, 4];
console.log('hello world');
上面代碼中胡陪,數(shù)組[1, 2, 3, 4]是一個值沥寥,會占用內存。變量arr是僅有的對這個值的引用柠座,因此引用次數(shù)為1邑雅。盡管后面的代碼沒有用到arr,它還是會持續(xù)占用內存妈经。
如果增加一行代碼淮野,解除arr對[1, 2, 3, 4]引用,這塊內存就可以被垃圾回收機制釋放了吹泡。
let arr = [1, 2, 3, 4];
console.log('hello world');
arr = null;
上面代碼中骤星,arr重置為null,就解除了對[1, 2, 3, 4]的引用爆哑,引用次數(shù)變成了0洞难,內存就可以釋放出來了。
因此揭朝,并不是說有了垃圾回收機制队贱,程序員就輕松了。你還是需要關注內存占用:那些很占空間的值潭袱,一旦不再用到柱嫌,你必須檢查是否還存在對它們的引用。如果是的話屯换,就必須手動解除引用编丘。
三、內存泄漏的識別方法
怎樣可以觀察到內存泄漏呢?
經驗法則是嘉抓,如果連續(xù)五次垃圾回收之后索守,內存占用一次比一次大,就有內存泄漏掌眠。這就要求實時查看內存占用蕾盯。
3.1 瀏覽器
Chrome 瀏覽器查看內存占用,按照以下步驟操作蓝丙。
1:打開開發(fā)者工具,選擇 Timeline 面板
2:在頂部的Capture字段里面勾選 Memory
3:點擊左上角的錄制按鈕望拖。
4:在頁面上進行各種操作渺尘,模擬用戶的使用情況。
5:一段時間后说敏,點擊對話框的 stop 按鈕鸥跟,面板上就會顯示這段時間的內存占用情況。
如果內存占用基本平穩(wěn)盔沫,接近水平医咨,就說明不存在內存泄漏。
反之架诞,就是內存泄漏了拟淮。