Reference Counting GC (อัลกอริทึมนับอ้างอิง)
อัลกอริทึม GC แบบเก่า/ง่ายที่สุด นับจำนวน Reference 指向 Object แต่ละตัว Ref Count = 0 → Collect ได้
ตัวอย่างทำงาน
var obj = { x: { y: 2 } }; // 2 Objects: obj (ref=1), obj.x (ref=1)
obj = 1; // obj เดิม ref=0, obj.x ref=0 → ทั้งคู่ Collect ได้
ข้อจำกัดร้ายแรง: Circular Reference
function f() {
var obj1 = {};
var obj2 = {};
obj1.p = obj2; // obj1 → obj2 (ref=1)
obj2.p = obj1; // obj2 → obj1 (ref=1) - Cycle!
}
f(); // Function Return → obj1, obj2 Out of Scope
// แต่ Ref Count = 1 ทั้งคู่ → ไม่ถูก Collect! (Memory Leak)
เหตุผลที่ JavaScript Engine สมัยใหม่ไม่ใช้ Reference Counting
- ไม่จัดการ Circular Reference ได้
- Overhead: Update Count ทุก Assignment
- ไม่เหมาะกับ Complex Object Graph
ที่ยังใช้ Reference Counting อยู่
- CPython (Python) - มี Cycle Detector แยก
- PHP (ก่อน 5.3)
- COM Objects (Windows)
- บาง Browser Engine สำหรับ DOM Nodes (Legacy IE)
JavaScript Modern: Mark-Sweep (Tracing GC)
แทนที่จะนับ Reference ให้ Trace จาก Root หา Reachable Objects
- แก้ Circular Reference ได้
- Generational GC (V8: Scavenge + Mark-Sweep-Compact)
- Incremental/Concurrent GC ลด Pause Time