JavaScript 記憶體洩漏檢測
- 
          
            JavaScript 中的 
意外全域性變數記憶體洩漏 - 
          
            使用
使用嚴格;避免 JavaScript 中的記憶體洩漏 - 
          
            使用
"use strict";來避免 JavaScript 中的全域性變數引起的記憶體洩漏 - 
          
            使用 
{once: true}和removeEventListener()避免 JavaScript 中的 DOM 引用不足導致的記憶體洩漏 - 
          
            
Forgotten Callbacks or Timer引起的記憶體洩漏及其預防技術 - 
          
            在 JavaScript 中如何避免
被遺忘的回撥或計時器 
不再需要記憶體洩漏的記憶體沒有返回到空閒記憶體池或作業系統。
在三種最常見的情況下可能會發生記憶體洩漏:意外全域性變數、忘記的回撥或計時器和 DOM 引用不足。
JavaScript 中的 意外全域性變數 記憶體洩漏
意外全域性變數未宣告為全域性變數。垃圾收集器無法收集它們,從而導致記憶體洩漏。
name 變數被建立為全域性 window.name,它分配的空間永遠不會被釋放。
function fn1() {
  // `name` is not declared
  name = new Array(99999999)
}
fn1();
使用使用嚴格;避免 JavaScript 中的記憶體洩漏
function fn1() {
  'use strict';
  name = new Array(99999999)
}
fn1();
輸出:

未使用變數未使用,需要刪除或正確處理以釋放記憶體空間。
最關鍵的一點是找到不再需要的記憶體。
JavaScript 使用垃圾收集器來確定程式碼的某個部分是否需要記憶體。
許多垃圾收集器使用 mark-and-sweep 演算法。
使用"use strict"; 來避免 JavaScript 中的全域性變數引起的記憶體洩漏
在 Chrome DevTools 的 Memory 標籤頁上使用 heap allocations。
你可以通過按 F12 或轉到 Right Click -> Inspect -> Memory 在 Chrome 中開啟 DevTools。
<!DOCTYPE html>
<html lang="en">
	<head>
 		<title>Document</title>
	</head>
	<body>
		<button id="leak-button">Start</button>
		<button id="stop-leak">Stop</button>
	<script>
    	var x=[];
    	var running = false;
    	function grow(){
 			x.push(new Array(1000000).join('x'));
 			if(running)
 				setTimeout(grow,1000);
 		}
    	$('#leak-button').click(function(){
 			running = true;
 			grow();
 		});
    	$('#stop-button').click(function(){
 			running = false;
 		});
 	</script>
 	</body>
</html>
輸出:

在這裡,每當使用者單擊開始按鈕並將包含百萬個 x 字元的字串推送到陣列中時,指令碼都會將 10.000 節點附加到 DOM。
即使在按下停止按鈕後,垂直的部分藍線也顯示記憶體洩漏。
變數 x 是記憶體洩漏的原因,因為它是一個全域性變數,即使不再需要它也會佔用空間。
使用 {once: true} 和 removeEventListener() 避免 JavaScript 中的 DOM 引用不足導致的記憶體洩漏
<!DOCTYPE html>
<html lang="en">
	<head>
 		<title>Document</title>
	</head>
	<body>
 		<button id="trigger">Trigger</button>
	<script>
		var clickElement = document.getElementById("click");
		const hugeString = new Array(100000).join('x');
		clickElement.addEventListener("click", function(){
            // hugeString is kept in the scope of callback forever
 			document.write(hugeString); 
		});
 	</script>
 </body>
</html>
輸出:
-to-Avoid-Memory-Leaks.webp)
活動的事件偵聽器可以防止變數被垃圾收集。
使用 removeEventListener() 或將第三個引數作為 {once: true} 傳遞。
這樣,執行一次。listener 方法將被自動刪除。
Forgotten Callbacks or Timer 引起的記憶體洩漏及其預防技術
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Document</title>
    </head>
	<body>
	<script>
 		for (var i = 0; i < 100000; i++) {
 			var obj = {
 				call_again: function() {
 				var message = this;
 				var value = setTimeout(function() {
 					message.callAgain();
     			}, 100000);
   			}
   		}
 		obj.call_again();
 		obj = null;
   	}
	</script>
	</body>>
</html>
輸出:

timer callback 和它的繫結物件 obj 直到超時結束才被釋放。
timer 可以自行重置並永遠執行。因此,記憶體空間將始終保留,永遠不會空閒。
在 JavaScript 中如何避免被遺忘的回撥或計時器
通過在 setTimeout() 或 setInterval() 中提供參考,並在不再需要它們時直接呼叫刪除該函式。
