บทความนี้อธิบายรายละเอียดเกี่ยวกับเวลาและวิธีการจัดการหน่วยความจำและการเปิดตัวโดย JavaScript และ IE เบราว์เซอร์หวังว่าจะเป็นประโยชน์ต่อนักพัฒนาส่วนหน้า
อินสแตนซ์ของหน่วยความจำรีลีส
การคัดลอกรหัสมีดังนี้:
<ภาษาสคริปต์ = "JavaScript">
-
strtest = "1";
สำหรับ (var i = 0; i <25; i ++)
-
strtest += strtest;
-
การแจ้งเตือน (strtest);
ลบ strtest;
collectgarbage ();
-
</script>
Collectgarbage เป็นคุณสมบัติเฉพาะของ IE ที่ใช้ในการปล่อยหน่วยความจำ วิธีการใช้งานควรเป็น: ตั้งค่าตัวแปรหรือวัตถุอ้างอิงเป็น null หรือลบจากนั้นดำเนินการปล่อย
เงื่อนไขที่จำเป็นสองประการจะต้องชัดเจนก่อนที่จะทำการรวบรวม:
การอ้างอิง - วัตถุนั้นไม่ถูกต้องนอกบริบทที่อาศัยอยู่
- วัตถุส่วนกลางจะไม่ถูกต้องหากไม่ได้ดำเนินการ (อ้างอิง)
การคัดลอกรหัสมีดังนี้:
-
// วัตถุ JavaScript จะล้มเหลวเมื่อใด
-
ฟังก์ชั่น testobject () {
var _obj1 = วัตถุใหม่ ();
-
ฟังก์ชั่น testobject2 () {
var _obj2 = วัตถุใหม่ ();
return _obj2;
-
// ตัวอย่าง 1
testobject ();
// ตัวอย่าง 2
testobject2 ()
// ตัวอย่าง 3
var obj3 = testobject2 ();
obj3 = null;
// ตัวอย่าง 4
var obj4 = testobject2 ();
var arr = [obj4];
obj3 = null;
arr = [];
ในสี่ตัวอย่างนี้:
- "ตัวอย่าง 1" สร้าง _OBJ1 ในฟังก์ชัน testObject () แต่เมื่อฟังก์ชั่นออกมันจะออกจากบริบทของฟังก์ชั่นดังนั้น _OBJ1 จึงไม่ถูกต้อง
- ใน "ตัวอย่าง 2" วัตถุ _OBJ2 ก็ถูกสร้างขึ้นใน testObject2 () และผ่านออกไปดังนั้นวัตถุจึงมีสภาพแวดล้อมบริบท (และอายุการใช้งาน) "นอกฟังก์ชั่น" แต่เนื่องจากค่าคืนของฟังก์ชันไม่ได้ "ถือ" โดยตัวแปรอื่น ๆ _OBJ2 ไม่ถูกต้องทันที
- ใน "ตัวอย่างที่ 3" _OBJ2 ที่สร้างโดย testObject2 () ถูกจัดขึ้นโดยตัวแปรภายนอก OBJ3 ในเวลานี้จนกว่าบรรทัดของรหัส "obj3 = null" จะมีผล _obj2 จะไม่ถูกต้องเนื่องจากความสัมพันธ์อ้างอิงหายไป
- ด้วยเหตุผลเดียวกับในตัวอย่างที่ 3, _OBJ2 ใน "ตัวอย่าง 4" จะไม่ถูกต้องหลังจากบรรทัดของรหัส "arr = []"
อย่างไรก็ตาม "ความล้มเหลว" ของวัตถุไม่รอที่จะ "ปล่อย" ภายในรันไทม์ JavaScript ไม่มีวิธีที่จะบอกผู้ใช้อย่างแน่นอนว่า "เมื่อใดที่วัตถุจะถูกปล่อยออกมา" ขึ้นอยู่กับกลไกการกู้คืนหน่วยความจำของ JavaScript - กลยุทธ์นี้คล้ายกับกลไกการรีไซเคิลใน. NET
ในรหัสตัวอย่างการดำเนินการ Excel ก่อนหน้านี้เจ้าของวัตถุนั่นคือ "excel.exe" จะเกิดขึ้นหลังจาก "การเปิดตัวของอินสแตนซ์ออบเจ็กต์ ActiveX" เท่านั้น การล็อคไฟล์และข้อมูลรับรองการอนุญาตของระบบปฏิบัติการเกี่ยวข้องกับกระบวนการ ดังนั้นหากวัตถุนั้นเป็นเพียง "ล้มเหลว" และไม่ใช่ "ปล่อย" กระบวนการอื่น ๆ จะมีปัญหาเมื่อประมวลผลไฟล์และอ้างถึงข้อมูลรับรองการอนุญาตของระบบปฏิบัติการ
- บางคนบอกว่านี่เป็นข้อผิดพลาดในกลไก JavaScript หรือ COM จริงๆแล้วมันไม่ใช่ สิ่งนี้เกิดจากความสัมพันธ์ที่ซับซ้อนระหว่างระบบปฏิบัติการเช่น JavaScript แทนที่จะเป็นปัญหาอิสระ
Microsoft ได้เปิดเผยกลยุทธ์ในการแก้ปัญหานี้: เรียกกระบวนการรีไซเคิลหน่วยความจำเชิงรุก
กระบวนการ collectgarbage () (มักจะเรียกว่ากระบวนการ GC) มีให้ใน (Microsoft) JScript กระบวนการ GC ใช้ในการทำความสะอาด "การจัดแนววัตถุที่ล้มเหลว" ใน IE ปัจจุบันนั่นคือกระบวนการทำลายล้างของการเรียกวัตถุ
ในตัวอย่างข้างต้นรหัสที่เรียกขั้นตอน GC คือ:
การคัดลอกรหัสมีดังนี้:
-
// วิธีการเรียกใช้มาตรฐานของขั้นตอน GC เมื่อประมวลผลวัตถุ ActiveX
-
ฟังก์ชั่น writexls () {
//(เล็กน้อย...)
Excel.quit ();
excel = null;
settimeout (collectgarbage, 1);
-
บรรทัดแรกของรหัสเรียกวิธี excel.quit () เพื่อให้กระบวนการ Excel ยกเลิกและออก ในเวลานี้เนื่องจากสภาพแวดล้อม JavaScript มีอินสแตนซ์ของวัตถุ Excel กระบวนการ Excel ไม่ได้ยกเลิกจริง
บรรทัดที่สองของโค้ดทำให้ Excel เป็นโมฆะเพื่อล้างการอ้างอิงวัตถุดังนั้น "ทำให้เป็นโมฆะ" วัตถุ อย่างไรก็ตามเนื่องจากวัตถุยังคงอยู่ในบริบทของฟังก์ชั่นหากเรียกใช้ขั้นตอน GC โดยตรงวัตถุจะยังไม่ถูกทำความสะอาด
บรรทัดที่สามของรหัสใช้ settimeout () เพื่อเรียกใช้ฟังก์ชัน collectgarbage และช่วงเวลาถูกตั้งค่าเป็น '1' ซึ่งทำให้กระบวนการ GC เกิดขึ้นหลังจากฟังก์ชั่น writexls () เท่านั้น ด้วยวิธีนี้วัตถุ Excel ตรงกับสองเงื่อนไขของ "สามารถทำความสะอาดได้โดย GC": ไม่มีการอ้างอิงและออกจากบริบท
การใช้ขั้นตอน GC นั้นมีประสิทธิภาพมากในสภาพแวดล้อม JS โดยใช้วัตถุ ActiveX ActiveXObjects ที่มีศักยภาพบางอย่าง ได้แก่ XML, VML, OWC (Web Componet), Flash และแม้แต่ Vbarray ใน JS จากมุมมองนี้เนื่องจากสถาปัตยกรรม AJAX ใช้ XMLHTTP และยังต้องตอบสนองคุณสมบัติ "No Page Switching" การเรียกกระบวนการ GC ในเวลาที่เหมาะสมจะให้ประสบการณ์ที่ดีขึ้นโดยใช้ UI
ในความเป็นจริงแม้กับกระบวนการ GC ปัญหา Excel ดังกล่าวจะไม่ได้รับการแก้ไขอย่างสมบูรณ์ เพราะคือแคชข้อมูลรับรองการอนุญาต วิธีเดียวที่จะทำให้ข้อมูลรับรองการอนุญาตของหน้าเว็บได้รับการอัปเดตคือ "เปลี่ยนเป็นหน้าใหม่"
ดังนั้นในความเป็นจริงในโครงการ SPS ที่กล่าวถึงข้างต้นวิธีที่ฉันใช้ไม่ใช่ GC แต่เป็นรหัสต่อไปนี้:
การคัดลอกรหัสมีดังนี้:
-
// รหัสการสลับเพจที่ใช้เมื่อประมวลผลวัตถุ ActiveX
-
ฟังก์ชั่น writexls () {
//(เล็กน้อย...)
Excel.quit ();
excel = null;
// รหัสต่อไปนี้ใช้ในการแก้ข้อบกพร่องในการเรียก Excel วิธีการที่มีให้ใน MSDN:
// settimeout (collectgarbage, 1);
// เนื่องจากสถานะที่เชื่อถือได้ของหน้าเว็บไม่สามารถล้างได้ (หรือซิงโครไนซ์) จะทำให้ Saveas () และวิธีการอื่น ๆ
// ไม่ถูกต้องในครั้งต่อไปที่คุณเรียกมัน
location.reload ();
-
คำอธิบายของตัวดำเนินการลบในคู่มือ
การอ้างอิงลบแอตทริบิวต์ออกจากวัตถุหรือลบองค์ประกอบออกจากอาร์เรย์
ลบนิพจน์
พารามิเตอร์นิพจน์เป็นนิพจน์ JScript ที่ถูกต้องมักจะเป็นชื่อคุณสมบัติหรือองค์ประกอบอาร์เรย์
อธิบาย
หากผลลัพธ์ของการแสดงออกเป็นวัตถุและแอตทริบิวต์ที่ระบุในนิพจน์มีอยู่และวัตถุไม่อนุญาตให้ลบออกเท็จจะถูกส่งกลับ
ในกรณีอื่น ๆ ทั้งหมดกลับมาจริง
ในที่สุดโน้ตเสริมเกี่ยวกับ GC: เมื่อแบบฟอร์ม IE ลดลงเช่นจะเรียกฟังก์ชัน collectgarbage () หนึ่งครั้ง สิ่งนี้ทำให้การใช้หน่วยความจำดีขึ้นอย่างมีนัยสำคัญหลังจากหน้าต่าง IE ลดลง