คำศัพท์เกี่ยวกับหน่วยความจำ

Meggin Kearney
Meggin Kearney

ส่วนนี้อธิบายคำศัพท์ทั่วไปที่ใช้ในการวิเคราะห์หน่วยความจำ และใช้ได้กับเครื่องมือต่างๆ ในการจัดทำโปรไฟล์หน่วยความจำสำหรับภาษาต่างๆ

คําศัพท์และแนวคิดที่อธิบายไว้ที่นี่หมายถึงเครื่องมือตรวจสอบกองขยะของเครื่องมือสําหรับนักพัฒนาเว็บใน Chrome หากคุณเคยใช้ Java, .NET หรือเครื่องมือวิเคราะห์หน่วยความจำอื่นๆ มาก่อน บทความนี้อาจช่วยทบทวนความรู้ได้

ขนาดของวัตถุ

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

การนำเสนอความทรงจำด้วยภาพ

ออบเจ็กต์สามารถเก็บหน่วยความจำได้ 2 วิธีดังนี้

  • โดยตรงจากออบเจ็กต์
  • โดยนัยคือเก็บการอ้างอิงไปยังออบเจ็กต์อื่นๆ ไว้ และป้องกันไม่ให้ตัวเก็บขยะ (หรือ GC) กำจัดออบเจ็กต์เหล่านั้นโดยอัตโนมัติ

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

คอลัมน์ขนาดแบบตื้นและแบบคงไว้ในแผงหน่วยความจํา

ขนาดระดับออบเจ็กต์

ค่านี้คือขนาดหน่วยความจำที่ออบเจ็กต์ใช้

ออบเจ็กต์ JavaScript ทั่วไปมีการจองหน่วยความจำบางส่วนไว้สำหรับคำอธิบายและสำหรับจัดเก็บค่าทันที โดยปกติแล้ว มีเพียงอาร์เรย์และสตริงเท่านั้นที่มีขนาดแบบตื้นที่สำคัญ อย่างไรก็ตาม สตริงและอาร์เรย์ภายนอกมักจะมีที่จัดเก็บหลักอยู่ในหน่วยความจําของโปรแกรมแสดงผล โดยจะแสดงเฉพาะออบเจ็กต์ Wrapper ขนาดเล็กในกองขยะ JavaScript

หน่วยความจําของโปรแกรมแสดงผลคือหน่วยความจําทั้งหมดของกระบวนการที่แสดงผลหน้าเว็บที่ตรวจสอบ: หน่วยความจําเนทีฟ + หน่วยความจํากองกอง JS ของหน้าเว็บ + หน่วยความจํากองกอง JS ของผู้ปฏิบัติงานเฉพาะทั้งหมดที่หน้าเว็บเริ่มต้น อย่างไรก็ตาม ออบเจ็กต์ขนาดเล็กก็สามารถเก็บหน่วยความจำจํานวนมากได้โดยอ้อม โดยการป้องกันการที่กระบวนการเก็บขยะอัตโนมัติจะนําออบเจ็กต์อื่นๆ ออก

ขนาดที่คงไว้

ค่านี้คือขนาดของหน่วยความจำที่ว่างขึ้นเมื่อลบออบเจ็กต์พร้อมกับออบเจ็กต์ที่เกี่ยวข้องซึ่งทำให้เข้าถึงจากรูท GC ไม่ได้

รูท GC ประกอบด้วยแฮนเดิลที่สร้าง (ทั้งแบบภายในหรือแบบภายนอก) เมื่อทำการอ้างอิงจากโค้ดเนทีฟไปยังออบเจ็กต์ JavaScript นอก V8 แฮนเดิลทั้งหมดดังกล่าวจะอยู่ในสแนปชอตกองที่อยู่ภายใต้รูท GC > ขอบเขตแฮนเดิล และรูท GC > แฮนเดิลส่วนกลาง การอธิบายแฮนเดิลในเอกสารประกอบนี้โดยไม่เจาะลึกรายละเอียดการใช้งานเบราว์เซอร์อาจทําให้สับสน คุณไม่จำเป็นต้องกังวลเกี่ยวกับทั้งรูท GC และตัวแฮนเดิล

มีรูท GC ภายในจำนวนมาก ซึ่งส่วนใหญ่ไม่น่าสนใจสำหรับผู้ใช้ รูทจากมุมมองแอปพลิเคชันมี 3 ประเภทดังนี้

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

กราฟหน่วยความจำเริ่มต้นด้วยรูท ซึ่งอาจเป็นออบเจ็กต์ window ของเบราว์เซอร์หรือออบเจ็กต์ Global ของโมดูล Node.js คุณไม่สามารถควบคุมวิธีจัดเก็บออบเจ็กต์รูทนี้ใน GC

ควบคุมออบเจ็กต์รูทไม่ได้

ทุกอย่างที่เข้าถึงจากรูทไม่ได้จะได้รับ GC

ต้นไม้ของออบเจ็กต์ที่เก็บรักษา

กองคือเครือข่ายของวัตถุที่เชื่อมต่อกัน ในวงการคณิตศาสตร์ โครงสร้างนี้เรียกว่ากราฟหรือกราฟความทรงจำ กราฟสร้างขึ้นจากโหนดที่เชื่อมต่อกันด้วยขอบ ซึ่งทั้ง 2 อย่างมีป้ายกำกับ

  • โหนด (หรือออบเจ็กต์) จะมีการติดป้ายกำกับโดยใช้ชื่อของฟังก์ชันคอนสตรัคเตอร์ที่ใช้สร้างโหนด
  • ขอบจะติดป้ายกำกับโดยใช้ชื่อพร็อพเพอร์ตี้

ดูวิธีบันทึกโปรไฟล์โดยใช้ Heap Profiler สิ่งที่น่าสนใจบางอย่างที่เราเห็นในการบันทึก Heap Profiler ต่อไปนี้ ได้แก่ ระยะทาง: ระยะทางจากรูท GC หากวัตถุเกือบทั้งหมดในประเภทเดียวกันอยู่ห่างจากกล้องในระยะเดียวกัน แต่มีวัตถุเพียงไม่กี่รายการที่อยู่ห่างจากกล้องในระยะที่ไกลกว่า ก็เป็นสิ่งที่ควรตรวจสอบ

ตัวอย่างระยะทางจากรูท

ผู้ควบคุม

ออบเจ็กต์ Dominator ประกอบด้วยโครงสร้างต้นไม้เนื่องจากแต่ละออบเจ็กต์มี Dominator เพียงรายการเดียว โดมิเนเตอร์ของออบเจ็กต์อาจไม่มีการอ้างอิงโดยตรงไปยังออบเจ็กต์ที่โดมิเนต กล่าวคือ ต้นไม้ของโดมิเนเตอร์ไม่ใช่ต้นไม้ที่ครอบคลุมของกราฟ

ในแผนภาพต่อไปนี้

  • โหนด 1 ควบคุมโหนด 2
  • โหนด 2 ควบคุมโหนด 3, 4 และ 6
  • โหนด 3 ควบคุมโหนด 5
  • โหนด 5 ครอบงำโหนด 8
  • โหนด 6 ครอบงำโหนด 7

โครงสร้างแผนผังโดมิเนเตอร์

ในตัวอย่างต่อไปนี้ โหนด #3 เป็นผู้ควบคุม #10 แต่ #7 ก็มีอยู่ในเส้นทางแบบง่ายทุกเส้นทางจาก GC ไปยัง #10 ด้วย ดังนั้น ออบเจ็กต์ ข จะเป็นผู้ควบคุมออบเจ็กต์ ก หาก ข อยู่ในเส้นทางที่ง่ายที่สุดทุกเส้นทางจากรูทไปยังออบเจ็กต์ ก

ภาพโดมิเนเตอร์แบบเคลื่อนไหว

ข้อมูลเฉพาะของ V8

เมื่อทำโปรไฟล์หน่วยความจำ การทำความเข้าใจสาเหตุที่ภาพรวมกองมีลักษณะหนึ่งๆ ย่อมมีประโยชน์ ส่วนนี้จะอธิบายหัวข้อที่เกี่ยวข้องกับหน่วยความจําบางหัวข้อซึ่งเกี่ยวข้องกับเครื่องเสมือน JavaScript ของ V8 (V8 VM หรือ VM) โดยเฉพาะ

การนําเสนอออบเจ็กต์ JavaScript

ประเภทพื้นฐานมี 3 ประเภท ได้แก่

  • ตัวเลข (เช่น 3.14159..)
  • บูลีน (จริงหรือเท็จ)
  • สตริง (เช่น 'Werner Heisenberg')

ไม่สามารถอ้างอิงค่าอื่นๆ และจะเป็นใบไม้หรือโหนดสิ้นสุดเสมอ

ตัวเลขสามารถจัดเก็บในรูปแบบใดรูปแบบหนึ่งต่อไปนี้

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

สตริงสามารถจัดเก็บไว้ในตำแหน่งใดตำแหน่งหนึ่งต่อไปนี้

  • กองขยะ VM หรือ
  • ภายนอกในหน่วยความจําของเรนเดอร์เออร์ ระบบจะสร้างและนําออบเจ็กต์ Wrapper ไปใช้สําหรับการเข้าถึงพื้นที่เก็บข้อมูลภายนอก เช่น แหล่งที่มาของสคริปต์และเนื้อหาอื่นๆ ที่ได้รับจากเว็บ แทนที่จะคัดลอกไปยังกอง VM

ระบบจะจัดสรรหน่วยความจําสําหรับออบเจ็กต์ JavaScript ใหม่จากฮีป JavaScript โดยเฉพาะ (หรือฮีป VM) ออบเจ็กต์เหล่านี้ได้รับการจัดการโดยเครื่องมือเก็บขยะของ V8 และจะยังคงอยู่ตราบใดที่มีการอ้างอิงถึงอย่างน้อย 1 รายการ

ออบเจ็กต์เนทีฟคือทุกอย่างที่ไม่ใช่กองขยะ JavaScript ออบเจ็กต์เนทีฟต่างจากออบเจ็กต์ฮีปตรงที่ตัวเก็บขยะ V8 จะไม่จัดการตลอดอายุการใช้งาน และเข้าถึงได้จาก JavaScript โดยใช้ออบเจ็กต์ Wrapper ของ JavaScript เท่านั้น

สตริง Cons คือออบเจ็กต์ที่ประกอบด้วยคู่สตริงที่จัดเก็บไว้แล้วรวมเข้าด้วยกัน และเป็นผลลัพธ์ของการต่อสตริง การรวมเนื้อหา cons string จะเกิดขึ้นเมื่อจําเป็นเท่านั้น ตัวอย่างเช่น เมื่อต้องสร้างสตริงย่อยของสตริงที่รวม

เช่น หากคุณต่อสตริง a และ b คุณจะได้รับสตริง (a, b) ซึ่งแสดงผลลัพธ์ของการต่อสตริง หากต่อท้าย d กับผลลัพธ์นั้นในภายหลัง คุณจะได้รับสตริงคอนสอีกรายการหนึ่ง ((a, b), d)

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

ออบเจ็กต์ JavaScript ทั่วไปอาจเป็นอาร์เรย์ประเภทใดประเภทหนึ่งต่อไปนี้ซึ่งใช้สำหรับจัดเก็บ

  • พร็อพเพอร์ตี้ที่มีชื่อ และ
  • องค์ประกอบตัวเลข

ในกรณีที่มีพร็อพเพอร์ตี้จำนวนน้อยมาก ระบบจะจัดเก็บพร็อพเพอร์ตี้เหล่านั้นไว้ในออบเจ็กต์ JavaScript โดยตรง

แผนที่ - ออบเจ็กต์ที่อธิบายประเภทของออบเจ็กต์และเลย์เอาต์ เช่น ระบบจะใช้แผนที่เพื่ออธิบายลําดับชั้นของออบเจ็กต์โดยนัยสําหรับการเข้าถึงพร็อพเพอร์ตี้อย่างรวดเร็ว

กลุ่มออบเจ็กต์

กลุ่มออบเจ็กต์เนทีฟแต่ละกลุ่มประกอบด้วยออบเจ็กต์ที่อ้างอิงซึ่งกันและกัน ตัวอย่างเช่น พิจารณาซับต้นไม้ DOM ที่ทุกโหนดมีลิงก์ไปยังโหนดหลัก รวมถึงลิงก์ไปยังโหนดย่อยและโหนดพี่น้องถัดไป เพื่อสร้างกราฟที่เชื่อมต่อกัน โปรดทราบว่าออบเจ็กต์เนทีฟจะไม่แสดงในกอง JavaScript ซึ่งเป็นเหตุผลที่ออบเจ็กต์เหล่านี้มีขนาดเป็น 0 ระบบจะสร้างออบเจ็กต์ Wrapper แทน

ออบเจ็กต์ Wrapper แต่ละรายการมีการอ้างอิงถึงออบเจ็กต์เนทีฟที่เกี่ยวข้องสําหรับการเปลี่ยนเส้นทางคําสั่งไปยังออบเจ็กต์นั้น กลุ่มออบเจ็กต์จะเก็บออบเจ็กต์ Wrapper ไว้ อย่างไรก็ตาม การดำเนินการนี้จะไม่สร้างวงจรที่รวบรวมไม่ได้ เนื่องจาก GC ฉลาดพอที่จะปล่อยกลุ่มออบเจ็กต์ที่ไม่มีการอ้างอิงถึง Wrapper อีกต่อไป แต่การลืมยกเลิกการระงับไฟล์กลุ่มเดียวจะระงับทั้งกลุ่มและไฟล์กลุ่มที่เกี่ยวข้อง