อัลกอริทึมการทำเครื่องหมายและกวาด
อัลกอริธึม Mark and Sweep มองหาวัตถุ 'ที่ไม่สามารถเข้าถึงได้' มากกว่าวัตถุ 'ที่ไม่ต้องการอีกต่อไป' อัลกอริธึมนี้เป็นการปรับปรุงอัลกอริธึมการนับอ้างอิง
อัลกอริธึมนี้ผ่าน 3 ขั้นตอนสำคัญจริงๆ
- รูท:โดยทั่วไป รูทคือตัวแปรส่วนกลางที่ใช้ในโค้ด วัตถุหน้าต่างในจาวาสคริปต์สามารถทำหน้าที่เป็นรูทได้ อัลกอริทึมนี้ใช้รูทอ็อบเจ็กต์ส่วนกลางเพื่อค้นหาว่าอ็อบเจ็กต์สามารถเข้าถึงได้หรือไม่สามารถเข้าถึงได้
- อัลกอรึทึมนี้จะตรวจสอบทุกรูทและรวมถึงลูกของมันด้วย ขณะตรวจสอบ วัตถุบางอย่างที่เข้าถึงได้จะถูกทำเครื่องหมายและวัตถุที่เหลือซึ่งไม่สามารถเข้าถึงได้จะไม่ถูกทำเครื่องหมายตามเงื่อนไขที่ให้ไว้
- วัตถุที่ไม่มีเครื่องหมาย หมายความว่าอะไรที่ไม่สามารถเข้าถึงได้จะถูกรวบรวมขยะ
มาร์คเฟส
ในระยะการทำเครื่องหมาย เราสามารถค้นหาได้ว่าองค์ประกอบใดถูกทำเครื่องหมายและสิ่งใดที่ไม่ได้ทำเครื่องหมาย สมมติว่ากำหนดคุณสมบัติ 'สวัสดี' ให้กับวัตถุ 'obj1' ตามที่แสดงในตัวอย่างที่ 1 ที่กำหนด รูท ซึ่งเป็นอ็อบเจ็กต์ส่วนกลางที่ใช้โดยอัลกอริธึมนี้ สามารถเข้าถึง obj1 และคุณสมบัติ 'hello' ดังนั้นมันจึงถูกทำเครื่องหมายในขณะนี้
ตัวอย่าง-1
var obj1 = { pro1: "hello" // marked because it can be reached by root. }
สำหรับสมมติว่าให้วัตถุนี้ได้รับการกำหนดค่าเป็น null ดังแสดงในตัวอย่างที่ 2 จากนั้น 'null' ที่ได้รับมอบหมายใหม่จะถูกทำเครื่องหมาย และ 'คุณสมบัติสวัสดี' ที่ได้รับมอบหมายก่อนหน้านี้จะไม่ถูกทำเครื่องหมาย ดังนั้น เมื่อสิ้นสุดระยะ Mark เราสามารถสรุปได้ว่าวัตถุที่กำหนดด้วย 'null' ถูกทำเครื่องหมาย และวัตถุที่กำหนดด้วย 'property hello' ไม่ถูกทำเครื่องหมาย
ตัวอย่าง-2
obj1 = null // null will be marked(reachable) and hello will be unmarked(unreachable)
ระยะการกวาด
ตามชื่อของมัน มันจะ 'กวาด' วัตถุที่ไม่สามารถเข้าถึงได้ ในระยะทำเครื่องหมาย เราเห็นว่าวัตถุที่มีคำว่า "สวัสดี" ถูกยกเลิกการทำเครื่องหมาย ทำให้ไม่สามารถเข้าถึงได้ เนื่องจากวัตถุที่ไม่สามารถเข้าถึงได้จะถูกรวบรวมเป็นขยะ วัตถุที่มี 'คุณสมบัติสวัสดี' จะถูกรวบรวมในขั้นตอนนี้
อัลกอริธึม Mark and Sweep เรียกอีกอย่างว่าตัวรวบรวมขยะการติดตาม เพราะมันติดตามคอลเล็กชันทั้งหมดของอ็อบเจ็กต์ที่โปรแกรมเข้าถึงได้โดยตรงหรือโดยอ้อม
วงจรไม่ใช่ปัญหาอีกต่อไป
ในตัวอย่างต่อไปนี้ เมื่อการเรียกใช้ฟังก์ชันส่งคืน ออบเจ็กต์ทั้งสอง obj1 และ obj2 จะไม่ถูกอ้างอิงโดยบางสิ่งที่สามารถเข้าถึงได้จากที่นั่นโดยมีสิทธิ์ในการรวบรวมขยะ ดังนั้นตัวรวบรวมขยะจะทำให้หน่วยความจำของวัตถุ obj1 และ obj2 ว่าง
ตัวอย่าง
function f() { var obj1 = {}; var obj2 = {}; obj1.p = obj2; // obj1 references obj2 obj2.p = obj1; // obj2 references obj1. This creates a cycle. } f();
ข้อจำกัด
มีบางช่วงเวลาที่สะดวกมากที่จะตัดสินใจด้วยตนเองว่าเมื่อใดและเมื่อใดที่จะปล่อยหน่วยความจำ เพื่อที่จะปล่อยหน่วยความจำของวัตถุนั้นจะต้องทำให้ไม่สามารถเข้าถึงได้อย่างชัดเจน กระบวนการทริกเกอร์การรวบรวมขยะใน JavaScript อย่างชัดเจนยังไม่สามารถทำได้ในขณะนี้