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

อธิบายรายละเอียดเกี่ยวกับหน่วยความจำรั่วใน JavaScript หรือไม่


หน่วยความจำรั่วใน JavaScript

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

JavaScript บางส่วนรั่วไหล

1) ตัวแปรส่วนกลางโดยไม่ได้ตั้งใจ

เมื่อมีการอ้างอิงตัวแปรที่ไม่ได้ประกาศ javascript จะสร้างตัวแปรใหม่ในวัตถุส่วนกลาง ในตัวอย่างที่ 1 ต่อไปนี้ สมมติว่าจุดประสงค์ของภาษาคือการอ้างอิงเฉพาะตัวแปรในฟังก์ชัน "myArray" ถ้าเราไม่ใช้ var เพื่อประกาศตัวแปรส่วนกลางจะถูกสร้างขึ้น อาจไม่ก่อให้เกิดอันตรายมากนัก แต่ปัญหาหลักเกิดขึ้นเมื่อตัวแปรส่วนกลางถูกสร้างขึ้นโดยใช้คีย์เวิร์ด "นี้" ดังแสดงในตัวอย่างที่ 2 โดยไม่ได้ตั้งใจ

ตัวอย่าง-1

function myArray(arg) {
   languages = "[javascript,.....]";  //  created using window
}

ตัวอย่าง-2

function myArray(arg) {
   this.languages = "[javascript,.....]";  // global object  
}

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

2) การปิด

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

ในตัวอย่างด้านล่าง เนื่องจากฟังก์ชันภายในทั้งหมดในการปิดใช้บริบทเดียวกัน innFun() จึงแชร์บริบทเดียวกันกับ "function() {}" ซึ่งส่งคืนโดยฟังก์ชันภายนอก ตอนนี้ ทุกๆ 3ms เราทำการเรียกใช้ฟังก์ชันไปที่ outFun ค่าใหม่ (หลังจากการเรียกแต่ละครั้ง) จะถูกกำหนดให้กับตัวแปรส่วนกลาง newvalue ตราบใดที่การอ้างอิงชี้ไปที่ "function() {}" นี้ ขอบเขตที่ใช้ร่วมกันจะยังคงอยู่และอาร์เรย์จะถูกเก็บไว้เพราะมันเป็นส่วนหนึ่งของฟังก์ชันภายใน (innFun) แม้ว่าจะไม่มีการเรียกฟังก์ชันภายในก็ตาม ทุกครั้งที่เราเรียกใช้ฟังก์ชันภายนอก (outFun) เราจะบันทึกฟังก์ชันก่อนหน้า (){} ในค่า (ตัวแปร) ของฟังก์ชันใหม่ ดังนั้น จึงต้องรักษาขอบเขตที่แชร์ไว้ก่อนหน้านี้อีกครั้ง ดังนั้นในการเรียกที่ n ของฟังก์ชันภายนอก (outFun) อาร์เรย์ของการเรียกภายนอก (n-1) จะไม่สามารถเก็บขยะได้ กระบวนการนี้จะหยุดเมื่อหน่วยความจำหมดในที่สุด

ตัวอย่าง

var newvalue;
function outFun() {
   var array = new Array(1000000);
   var value = newvalue;
      function innFun() {
        if (value) return array;
   }
   return function () {};
}
setInterval(function () {
   newvalue = outFun();
   }, 3);