Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Javascript

การกำจัดการรั่วไหลของหน่วยความจำใน Javascript


สาเหตุหลักของการรั่วไหลในภาษาที่รวบรวมโดยขยะคือการอ้างอิงที่ไม่ต้องการ เพื่อให้เข้าใจถึงการรั่วไหลของหน่วยความจำ ให้เรามาดูกันว่าหน่วยความจำ (การรวบรวมขยะ) ทำงานอย่างไร

อัลกอริทึมการทำเครื่องหมายและกวาด −อัลกอริธึมนี้ลดคำจำกัดความของ "วัตถุไม่จำเป็นอีกต่อไป" เป็น "วัตถุที่ไม่สามารถเข้าถึงได้" อัลกอริธึมนี้ถือว่าความรู้เกี่ยวกับชุดของอ็อบเจ็กต์ที่เรียกว่ารูท ใน JavaScript รูทคืออ็อบเจ็กต์ส่วนกลาง GC จะเริ่มต้นจากรากเหล่านี้เป็นระยะ ค้นหาวัตถุทั้งหมดที่อ้างอิงจากรากเหล่านี้แบบเรียกซ้ำ เริ่มจากราก GC จะค้นหาวัตถุที่เข้าถึงได้ทั้งหมดและรวบรวมวัตถุที่ไม่สามารถเข้าถึงได้ทั้งหมด

ประเภทของหน่วยความจำรั่ว

1. ตัวแปรสากล(ไม่ประกาศ/อุบัติเหตุ)

ใน JS คุณสามารถประกาศตัวแปรได้ทั่วโลกโดยไม่ได้ตั้งใจ หากคุณไม่ได้ระบุคำสำคัญสำหรับการประกาศ (let, var, const) JS ค้นหาการย้ายออกในขอบเขตจนกว่าจะถึงขอบเขตสากล และหากไม่พบตัวแปรในขอบเขตใดๆ จะสร้างตัวแปรส่วนกลาง

ตัวอย่าง

function test() {
   a = [1, 2, 3]
}
test()
// a was initialized without declaration using a keyword and is now in the global scope.
console.log(a)

ผลลัพธ์

[1, 2, 3]

ลักษณะการทำงานนี้อาจทำให้หน่วยความจำรั่วได้ เนื่องจากตัวแปรมีอยู่ในขอบเขตทั่วโลกโดยไม่รู้ตัวและจะไม่ปล่อยให้ว่างเว้นแต่โปรแกรมจะสิ้นสุด ซึ่งสามารถแก้ไขได้โดยใช้คำสำคัญสำหรับการประกาศ

2. ปิด

หน่วยความจำรั่วจะเกิดขึ้นในการปิดหากมีการประกาศตัวแปรในฟังก์ชันภายนอกและจะพร้อมใช้งานโดยอัตโนมัติสำหรับฟังก์ชันภายในที่ซ้อนกันและยังคงอยู่ในหน่วยความจำแม้ว่าจะไม่ได้ถูกใช้/อ้างอิงในฟังก์ชันที่ซ้อนกัน

3. DOM ที่แยกออก/การอ้างอิงจาก DOM

DOM เป็นทรีที่เชื่อมโยงแบบทวีคูณ การมีการอ้างอิงถึงโหนดใดๆ ในทรีจะป้องกันทรีทั้งหมดจากการรวบรวมขยะ DOM ที่แยกออกมาหรือการอ้างอิง Out of DOM หมายความว่าโหนดที่ถูกลบออกจาก DOM แต่อยู่ในหน่วยความจำผ่าน JS หมายความว่าตราบใดที่ยังมีการอ้างอิงถึงตัวแปรหรืออ็อบเจ็กต์ที่ใดก็ตาม ออบเจ็กต์นั้นจะไม่ถูกรวบรวมเป็นขยะแม้ว่าจะถูกลบออกจาก DOM แล้ว ลบการอ้างอิงออกจาก JS ทุกครั้งเมื่อคุณทำ DOM บางส่วนเสร็จแล้ว

4. ผู้ฟังเหตุการณ์

addEventListener() วิธีการแนบตัวจัดการเหตุการณ์กับองค์ประกอบและสามารถเพิ่มตัวจัดการเหตุการณ์หลายตัวในองค์ประกอบเดียว หากองค์ประกอบ DOM และผู้ฟังเหตุการณ์ไม่มีวงจรชีวิตที่เหมือนกัน ก็อาจทำให้หน่วยความจำรั่วได้