บทนำ
คุณควรใช้memory_get_usage(false)
เพราะสิ่งที่คุณต้องการคือหน่วยความจำที่ใช้ไม่ใช่หน่วยความจำที่จัดสรร
อะไรคือความแตกต่าง
คุณGoogle Mail
อาจจัดสรร25MB
พื้นที่เก็บข้อมูลให้คุณ แต่ไม่ได้หมายความว่าเป็นสิ่งที่คุณใช้ในขณะนี้
นี่คือสิ่งที่เอกสาร PHP บอก
ตั้งค่านี้เป็น TRUE เพื่อรับขนาดจริงของหน่วยความจำที่จัดสรรจากระบบ หากไม่ได้ตั้งค่าหรือ FALSE จะมีการรายงานเฉพาะหน่วยความจำที่ใช้โดย emalloc ()
อาร์กิวเมนต์ทั้งสองจะส่งคืนหน่วยความจำที่จัดสรรโดยสัมพันธ์กับขีด จำกัด หน่วยความจำ แต่ข้อแตกต่างหลักคือ:
memory_get_usage(false)
ให้หน่วยความจำที่ใช้emalloc()
ในขณะที่memory_get_usage(true)
ส่งกลับเหตุการณ์สำคัญซึ่งสามารถสาธิตได้ที่นี่Memory Mile Store
ฉันต้องการทราบว่าสคริปต์ใกล้ถึงขีด จำกัด นั้นแค่ไหน
ซึ่งจะต้องใช้คณิตศาสตร์บางส่วนและอาจใช้ได้เฉพาะในลูปหรือกรณีการใช้งานที่เฉพาะเจาะจงเท่านั้น ทำไมฉันถึงพูดแบบนั้น?
ลองนึกภาพ
ini_set('memory_limit', '1M');
$data = str_repeat(' ', 1024 * 1024);
The above script would fail before you even get the chance to start start checking memory
.
เท่าที่ฉันรู้วิธีเดียวที่ฉันสามารถตรวจสอบหน่วยความจำที่ใช้สำหรับตัวแปรหรือส่วนเฉพาะของ PHP คือ:
$start_memory = memory_get_usage();
$foo = "Some variable";
echo memory_get_usage() - $start_memory;
ดูคำอธิบายแต่ถ้าคุณอยู่ในฟังก์ชั่นวนซ้ำหรือวนซ้ำคุณสามารถใช้การใช้หน่วยความจำสูงสุดเพื่อประเมินอย่างปลอดภัยเมื่อหน่วยความจำจะมาถึง
ตัวอย่าง
ini_set('memory_limit', '1M');
$memoryAvailable = filter_var(ini_get("memory_limit"), FILTER_SANITIZE_NUMBER_INT);
$memoryAvailable = $memoryAvailable * 1024 * 1024;
$peekPoint = 90;
$memoryStart = memory_get_peak_usage(false);
$memoryDiff = 0;
$stat = array(
"HIGHEST_MEMORY" => 0,
"HIGHEST_DIFF" => 0,
"PERCENTAGE_BREAK" => 0,
"AVERAGE" => array(),
"LOOPS" => 0
);
$data = "";
$i = 0;
while ( true ) {
$i ++;
$memoryUsed = memory_get_peak_usage(false);
$memoryDiff = $memoryUsed - $memoryStart;
$memoryStart = memory_get_peak_usage(false);
$stat['HIGHEST_MEMORY'] = $memoryUsed > $stat['HIGHEST_MEMORY'] ? $memoryUsed : $stat['HIGHEST_MEMORY'];
$stat['HIGHEST_DIFF'] = $memoryDiff > $stat['HIGHEST_DIFF'] ? $memoryDiff : $stat['HIGHEST_DIFF'];
$stat['AVERAGE'][] = $memoryDiff;
$stat['LOOPS'] ++;
$percentage = (($memoryUsed + $stat['HIGHEST_DIFF']) / $memoryAvailable) * 100;
if ($percentage > $peekPoint) {
print(sprintf("Stoped at: %0.2f", $percentage) . "%\n");
$stat['AVERAGE'] = array_sum($stat['AVERAGE']) / count($stat['AVERAGE']);
$stat = array_map(function ($v) {
return sprintf("%0.2f", $v / (1024 * 1024));
}, $stat);
$stat['LOOPS'] = $i;
$stat['PERCENTAGE_BREAK'] = sprintf("%0.2f", $percentage) . "%";
echo json_encode($stat, 128);
break;
}
$data .= str_repeat(' ', 1024 * 25);
}
เอาต์พุต
Stoped at: 95.86%
{
"HIGHEST_MEMORY": "0.71",
"HIGHEST_DIFF": "0.24",
"PERCENTAGE_BREAK": "95.86%",
"AVERAGE": "0.04",
"LOOPS": 11
}
การสาธิตสด
สิ่งนี้อาจยังล้มเหลว
มันอาจจะล้มเหลวเพราะหลังจากif ($percentage > $peekPoint) {
นี้ยังคงเพิ่มเพื่อทำงานเพิ่มเติมโดยยังใช้หน่วยความจำอีกด้วย
print(sprintf("Stoped at: %0.2f", $percentage) . "%\n");
$stat['AVERAGE'] = array_sum($stat['AVERAGE']) / count($stat['AVERAGE']);
$stat = array_map(function ($v) {
return sprintf("%0.2f", $v / (1024 * 1024));
}, $stat);
$stat['LOOPS'] = $i;
$stat['PERCENTAGE_BREAK'] = sprintf("%0.2f", $percentage) . "%";
echo json_encode($stat, 128);
break;
If the memory to process this request is grater than the memory available the script would fail.
สรุป
ไม่ใช่วิธีการแก้ปัญหาที่สมบูรณ์แบบ แต่ตรวจสอบหน่วยความจำในช่วงเวลาและหากมีการมองเกิน (เช่น 90%) ใน exit
ทันทีและปล่อยให้สิ่งที่น่าสนใจ