JavaScript 記憶體洩漏 淺談面試必問的 Memory Leak 問題

Lin Yen-Cheng on 2019-10-01 3 min. read

記憶體管理

在有垃圾回收機制的語言中,我們無法像 c 或是 c++ 那樣手動管理,都是透過機制來自動回收的。

開始工作後寫的兩個語言 Java 和 JavaScript 都是有垃圾回收機制的語言,所以在 Java 的啟動參數中,也會有給 JVM 的 GC 選項像是 -XX:+ParallelRefProcEnabled,而回收的一個重點,就是要讓機器認知到說這個物件不會再用到了。

記憶體洩漏情境

而在 JavaScript 中,最重要的就是要讓這個變數不要再被參照到,以下情境都可能遇到:

  • 全域變數: 避免 closure 去 access 到全域變數,像是 setInterval 遇上 closure
function foo(arg) {
  bar = "this is a hidden global variable";
  //  window.bar = "this is a hidden global variable";
}
  • 多或循環參照: 同時太多地方去 access 同個物件
  • 事件重複監聽: 可能在未注意的情況下就一直增加監聽,舉 Socket.IO 的例子來說,主要是以下兩個功能:
    • 監聽訂閱的訊息
    • 針對監聽到的訊息再發送訊息

在這兩個功能互動的過程中,如果需要和 react 搭配使用,就要注意:

  • 不要重複的去產生新的 socket
  • 不要重複的去監聽事件

觀察與解決記憶體洩漏

  1. 使用 delete 和將變數設為 null,手動告訴機器這個物件沒有使用了
var myVar = "Hello";
var myVar1 = myVar;
myVar = null;
delete myVar;
console.log(myVar1);
  1. 利用開發者工具中的快照,簡單用法就是使用一陣子之後重新抓一次快照,觀察記憶體有沒有上升太多
  2. 事件中的 listener 可以放個 console.log('避免重複監聽')

參考連結:

https://developers.google.com/web/tools/chrome-devtools/memory-problems/?hl=zh-tw
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Memory_Management


喜歡這篇文章,請幫忙拍拍手喔 🤣

share