คำแนะนำในการดำเนินการ
1. เพิ่มตัวนับอ้างอิงให้กับวัตถุ ค่าของตัวนับอ้างอิงจะเพิ่มขึ้นทุกครั้งที่อยู่ที่ไหนสักแห่ง เมื่อใดก็ตามที่การอ้างอิงไม่ถูกต้อง ตัวนับจะลดลงหนึ่ง
หากการนับซ้ำของค่าตัวแปรลดลงหนึ่งและเท่ากับ 0 ค่านั้นจะถูกปล่อยและไม่ใช่ขยะ คนเก็บขยะไม่จัดการมัน
หากการนับซ้ำของค่าตัวแปรมากกว่า 0 หลังจากลดลงหนึ่งค่า จะถือว่าค่านั้นไม่สามารถปล่อยออกได้และอาจกลายเป็นขยะ
2. พนักงานเก็บขยะจะรวบรวมขยะที่เป็นไปได้ เมื่อถึงจำนวนที่กำหนดแล้ว ระบบจะเริ่มโปรแกรมระบุขยะและปล่อยขยะจริง
ตัวอย่าง
<?php // กรณีกลไกการรวบรวมขยะ PHP: โปรดดูคู่มือ PHP //-------------------ประเภทสเกลาร์-------------------- // เคล็ดลับ: ตัวแปร PHP แต่ละตัวมีอยู่ในคอนเทนเนอร์ตัวแปรที่เรียกว่า "zval" ซึ่งมีประเภทและค่าของตัวแปร "is_ref": ไม่ว่าจะเป็นตัวแปรอ้างอิงหรือไม่ "refcount": จำนวนการอ้างอิง // ตัวอย่าง: สร้างคอนเทนเนอร์ zval ใหม่ $a = 'สตริงใหม่'; // เช่น: แสดงข้อมูลคอนเทนเนอร์ zval xdebug_debug_zval('a'); // a: (refcount=1, is_ref=0),string 'new string' (length=10) // ตัวอย่าง: เพิ่มจำนวนการอ้างอิงของคอนเทนเนอร์ zval $c = $b = $a; xdebug_debug_zval('a'); // a:(refcount=3, is_ref=0),สตริง 'สตริงใหม่' (ความยาว=10) xdebug_debug_zval('b'); // b:(refcount=3, is_ref=0),สตริง 'สตริงใหม่' (ความยาว=10) xdebug_debug_zval('c'); // c:(refcount=3, is_ref=0),สตริง 'สตริงใหม่' (ความยาว=10) // เคล็ดลับ: ขณะนี้มีเพียงคอนเทนเนอร์เดียวเท่านั้น เนื่องจาก PHP จะไม่คัดลอกคอนเทนเนอร์ตัวแปรที่สร้างขึ้นเมื่อไม่จำเป็น // ในขณะนี้ คอนเทนเนอร์ตัวแปรนี้เชื่อมโยงกับตัวแปร a ตัวแปร b และตัวแปร c unset($b); // เช่น: ลดจำนวนการอ้างอิง xdebug_debug_zval('a'); // a:(refcount=2, is_ref=0),string 'new string' (length=10) // เคล็ดลับ: unset เมื่อลบตัวแปร จำนวนตัวแปร refcount จะลดลงหนึ่งตัว ในขณะนี้ มีเพียง $a และ $b เท่านั้นที่ชี้ไปที่คอนเทนเนอร์ตัวแปร ไม่ได้ตั้งค่า($a); ไม่ได้ตั้งค่า($c); var_dump($a); // เคล็ดลับ: ในขณะนี้ การนับใหม่เป็น 0 และตัวแปรจะถูกลบ // เมื่อการนับใหม่กลายเป็น 0 คอนเทนเนอร์ตัวแปรที่มีประเภทและค่าจะถูกลบออกจากหน่วยความจำ //---------------------------------- ประเภทคอมโพสิต------------- echo '--------------ประเภทคอมโพสิต-------------<br/>'; $a = อาร์เรย์( 'ชื่อ' => 'จูเนียร์', 'อายุ' => 18 - xdebug_debug_zval('a'); // a:(refcount=1, is_ref=0), // อาร์เรย์ (ขนาด = 2) // 'ชื่อ' => (refcount=1, is_ref=0),สตริง 'จูเนียร์' (ความยาว=6) // 'อายุ' => (refcount=1, is_ref=0),int 18 // เช่น: เพิ่มองค์ประกอบที่มีอยู่แล้วในอาร์เรย์ $a['love'] = $a['name']; xdebug_debug_zval('a'); // a:(refcount=1, is_ref=0), // อาร์เรย์ (ขนาด = 3) // 'name' => (refcount=2, is_ref=0),string 'junior' (ความยาว=6) // 'อายุ' => (refcount=1, is_ref=0),int 18 // 'love' => (refcount=2, is_ref=0),string 'junior' (ความยาว=6) // $a = array('หนึ่ง'); // xdebug_debug_zval('a'); // // $b = &$a; // $c = $a; // $b = &$c; // xdebug_debug_zval('b'); // xdebug_debug_zval('c'); // xdebug_debug_zval('a'); // ทำความสะอาดปัญหาคอนเทนเนอร์ตัวแปร echo '------------ ปัญหาหน่วยความจำรั่ว -----------<br/>'; $a = array('one'); xdebug_debug_zval('a'); // a:(refcount=1, is_ref=0), // อาร์เรย์ (ขนาด = 1) // 0 => (refcount=1, is_ref=0),สตริง 'หนึ่ง' (ความยาว=3) $a[] = &$a; xdebug_debug_zval('a'); // a:(refcount=2, is_ref=1), // อาร์เรย์ (ขนาด = 2) // 0 => (refcount=1, is_ref=0),สตริง 'หนึ่ง' (ความยาว=3) // 1 => (refcount=2, is_ref=1), // &อาร์เรย์ // ยกเลิกการตั้งค่า($a); // (refcount=1, is_ref=1)=array ( // 0 => (refcount=1, is_ref=0)='one', // 1 => (refcount=1, is_ref=1)=... - // เคล็ดลับ: หลังจาก unset($a) จำนวนการอ้างอิงจะลดลงหนึ่ง แม้ว่าจะไม่มีสัญลักษณ์ใดๆ ในขอบเขตที่ชี้ไปที่โครงสร้างนี้อีกต่อไป (นั่นคือ คอนเทนเนอร์ตัวแปร) // เนื่องจากองค์ประกอบอาร์เรย์ "1" ยังคงชี้ไปที่อาร์เรย์เอง จึงไม่สามารถล้างคอนเทนเนอร์นี้ได้ // เนื่องจากไม่มีสัญลักษณ์อื่นที่ชี้ไป ผู้ใช้จึงไม่สามารถล้างโครงสร้างนี้ได้ ส่งผลให้หน่วยความจำรั่ว // โชคดี , PHP จะล้างโครงสร้างข้อมูลนี้เมื่อสิ้นสุดการเรียกใช้สคริปต์ แต่หน่วยความจำจำนวนมากจะถูกใช้ก่อนที่ PHP จะล้างข้อมูล // สิ่งเดียวกันนี้เกิดขึ้นกับวัตถุ อันที่จริงมันมีแนวโน้มที่จะเกิดขึ้นกับวัตถุมากกว่าเพราะว่าวัตถุนั้นมีการอ้างอิงโดยปริยายเสมอ
ข้างต้นคือวิธีที่การนับการอ้างอิง PHP ใช้การรวบรวมขยะ ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน