
คำแนะนำในการดำเนินการ
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 ใช้การรวบรวมขยะ ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน