Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> JavaScript

การกำจัด Memory Leaks ใน JavaScript

สาเหตุหลักของ leaks ในภาษาที่มี garbage collection คือ unwanted references เพื่อเข้าใจ memory leaks มาดู memory freeing (garbage collection) ทำงานยังไง

Mark-and-sweep algorithm - อัลกอริทึมนี้ลดนิยาม "ออบเจ็กต์ไม่จำเป็นแล้ว" เป็น "ออบเจ็กต์เข้าถึงไม่ได้" สมมติรู้จักชุดออบเจ็กต์ที่เรียกว่า roots ใน JS root คือ global object เป็นระยะ GC เริ่มจาก roots หาออบเจ็กต์ที่ถูกอ้างอิงจาก roots แบบ recursive จาก roots GC จะหาออบเจ็กต์ที่เข้าถึงได้ทั้งหมดและเก็บออบเจ็กต์ที่เข้าถึงไม่ได้

ประเภทของ Memory Leaks

1. Global variables (undeclared/accidental)

ใน JS คุณสามารถประกาศตัวแปร global โดยไม่ได้ตั้งใจหากไม่ระบุ declaration keyword (let, var, const) JS ค้นหาขยับออกใน scope จนถึง global scope ถ้าไม่เจอตัวแปรใน scope ใด จะสร้าง global variable

ตัวอย่าง

function test() {    a = [1, 2, 3] } test() // a ถูก initialize โดยไม่มี declaration keyword และอยู่ใน global scope ตอนนี้ console.log(a)

ผลลัพธ์

[1, 2, 3]

พฤติกรรมนี้ก่อให้เกิด memory leaks เพราะตัวแปรอยู่ใน global scope โดยไม่รู้ตัว และไม่ถูกปล่อยจนกว่าโปรแกรมจะจบ แก้ได้โดยใช้ declaration keyword

2. Closures

Memory leak ใน closure เกิดขึ้นถ้าตัวแปรประกาศใน outer function และกลายเป็น available ให้ inner function แบบอัตโนมัติ และคงอยู่ในหน่วยความจำแม้ไม่ได้ใช้/อ้างอิงใน nested function

3. Detached DOM/Out of DOM Reference

DOM เป็น doubly-linked tree การมี reference ไปยัง node ใดใน tree จะป้องกันทั้ง tree จาก garbage collection Detached DOM หรือ Out of DOM reference หมายถึง nodes ที่ถูกลบออกจาก DOM แต่ยังอยู่ในหน่วยความจำผ่าน JS หมายถึงตราบใดที่ยังมี reference ไปยังตัวแปรหรือออบเจ็กต์ไหนที่ไหน ออบเจ็กต์นั้นจะไม่ถูก garbage collected แม้ถูกลบออกจาก DOM แล้ว ต้องลบ reference จาก JS เมื่อทำเสร็จกับส่วนของ DOM

4. Event Listeners

เมธอด addEventListener() ผูก event handler กับ element และสามารถเพิ่ม multiple event handlers ให้ element เดียวได้ หาก DOM element และ event listener ไม่มี lifecycle เหมือนกัน อาจก่อให้เกิด memory leak