Jika real_usage
argumen disetel ke true
PHP DOCS, katakan itu akan mendapatkan ukuran sebenarnya dari memori yang dialokasikan dari sistem. Jika itu false
akan mendapatkan memori yang dilaporkan olehemalloc()
Manakah dari 2 opsi ini yang mengembalikan nilai maks. memori yang dialokasikan relatif terhadap nilai batas memori di php.ini?
Saya ingin tahu seberapa dekat skrip mencapai batas itu.
php
memory
memory-management
thelolcat
sumber
sumber
Jawaban:
Oke, mari kita uji ini menggunakan skrip sederhana:
ini_set('memory_limit', '1M'); $x = ''; while(true) { echo "not real: ".(memory_get_peak_usage(false)/1024/1024)." MiB\n"; echo "real: ".(memory_get_peak_usage(true)/1024/1024)." MiB\n\n"; $x .= str_repeat(' ', 1024*25); //store 25kb more to string }
Keluaran:
not real: 0.73469543457031 MiB real: 0.75 MiB not real: 0.75910949707031 MiB real: 1 MiB ... not real: 0.95442199707031 MiB real: 1 MiB not real: 0.97883605957031 MiB real: 1 MiB PHP Fatal error: Allowed memory size of 1048576 bytes exhausted (tried to allocate 793601 bytes) in /home/niko/test.php on line 7
Sepertinya penggunaan sebenarnya adalah memori yang dialokasikan dari sistem - yang tampaknya dialokasikan dalam bucket yang lebih besar daripada yang saat ini dibutuhkan oleh skrip. (Saya kira karena alasan kinerja). Ini juga merupakan memori yang digunakan proses php.
The
$real_usage = false
penggunaan adalah penggunaan memori Anda benar-benar digunakan dalam naskah Anda, bukan jumlah aktual memori yang dialokasikan oleh manajer memori Zend.Baca pertanyaan ini untuk informasi lebih lanjut.
Singkatnya: untuk mengetahui seberapa dekat Anda dengan batas memori, gunakan
$real_usage = true
sumber
if (segment_size < true_size || heap->real_size + segment_size > heap->limit) { /* Memory limit overflow */
.emalloc
(ditambah byte untuk header dan penyelarasan memori). Itu tidak mencerminkan memori yang terbuang karena blok tidak pas dengan ruang yang tersisa di segmen yang sudah dialokasikan. Jika Anda mengubah contoh Anda untuk mengalokasikan (1024 * 256) byte dan batas 2M, perbedaan dua akan menjadi lebih jelas.memory_get_usage(true)
pengembalian yang harus dibandingkanmemory_limit
. Contoh yang diberikan dalam jawaban terlalu sederhana karena tidak ada "memori yang terbuang". Apa yang terjadi adalah bahwa memori yang dialokasikan "sebenarnya" perlu ditingkatkan dari "1 MiB" menjadi "1,25 MiB" dan itulah yang memicu kesalahan fatal Saya memiliki skrip batch kompleks dengan batas memori 120 MiB yang memiliki memori yang dialokasikan "tidak nyata" hanya "80 MiB" saat dibatalkan karena memori yang dialokasikan "sebenarnya" mencapai batas.pengantar
Anda harus menggunakan
memory_get_usage(false)
karena yang Anda inginkan adalah memori yang digunakan bukan memori yang dialokasikan.Apa bedanya
Anda
Google Mail
mungkin telah mengalokasikan25MB
penyimpanan untuk Anda tetapi itu tidak berarti itulah yang telah Anda gunakan saat ini.Ini persis seperti yang dikatakan oleh dokumen PHP
Kedua argumen tersebut akan mengembalikan memori yang dialokasikan relatif terhadap batas memori tetapi perbedaan utamanya adalah:
memory_get_usage(false)
Berikan memori yang digunakanemalloc()
saatmemory_get_usage(true)
mengembalikan tonggak yang bisa didemonstrasikan di sini Memory Mile StoreSaya ingin tahu seberapa dekat skrip mencapai batas itu.
Itu akan membutuhkan beberapa matematika dan mungkin hanya berfungsi dalam loop atau kasus penggunaan tertentu. Mengapa saya mengatakan seperti itu?
Membayangkan
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
.Sejauh yang saya tahu, satu-satunya cara saya dapat memeriksa memori yang digunakan untuk variabel atau bagian tertentu dari PHP adalah:
$start_memory = memory_get_usage(); $foo = "Some variable"; echo memory_get_usage() - $start_memory;
Lihat Penjelasan , tetapi jika Anda berada dalam fungsi loop atau rekursif, Anda dapat menggunakan penggunaan memori maksimum untuk memperkirakan dengan aman kapan intip memori akan tercapai.
Contoh
ini_set('memory_limit', '1M'); $memoryAvailable = filter_var(ini_get("memory_limit"), FILTER_SANITIZE_NUMBER_INT); $memoryAvailable = $memoryAvailable * 1024 * 1024; $peekPoint = 90; // 90% $memoryStart = memory_get_peak_usage(false); $memoryDiff = 0; // Some stats $stat = array( "HIGHEST_MEMORY" => 0, "HIGHEST_DIFF" => 0, "PERCENTAGE_BREAK" => 0, "AVERAGE" => array(), "LOOPS" => 0 ); $data = ""; $i = 0; while ( true ) { $i ++; // Get used memory $memoryUsed = memory_get_peak_usage(false); // Get Diffrence $memoryDiff = $memoryUsed - $memoryStart; // Start memory Usage again $memoryStart = memory_get_peak_usage(false); // Gather some stats $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; // var_dump($percentage, $memoryDiff); // Stop your scipt 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); // 1kb every time }
Keluaran
Stoped at: 95.86% { "HIGHEST_MEMORY": "0.71", "HIGHEST_DIFF": "0.24", "PERCENTAGE_BREAK": "95.86%", "AVERAGE": "0.04", "LOOPS": 11 }
Demo Langsung
Ini mungkin masih gagal
Mungkin gagal karena setelah
if ($percentage > $peekPoint) {
ini masih menambah untuk melakukan tugas tambahan dengan juga memakan memoriprint(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.
Kesimpulan
Ini bukan solusi sempurna tetapi periksa memori pada interval dan jika melebihi mengintip (misalnya 90%) secara
exit
instan dan tinggalkan barang mewahsumber
memory_limit
opsi tentang heap? atau tumpukan?real_usage
false melaporkan penggunaan skrip Anda yang digunakan . Ini akan menjadi yang lebih akurat dari keduanya.real_usage
true melaporkan memori yang dialokasikan ke skrip Anda. Ini akan menjadi yang lebih tinggi dari keduanya.Saya mungkin akan menggunakan
true
jika saya mencoba membandingkan, karena skrip Anda tidak akan pernah dialokasikan lebih dari batas memori, dan akan terus berjalan selama itu (ditambah semua skrip lainnya) tidak melebihi penggunaan itu.sumber
false
apakah memori yang digunakan skrip ,true
adalah memori yang dialokasikan .sesuai PHP memory_get_usage
jadi untuk mendapatkan memori yang digunakan oleh skrip Anda, Anda harus menggunakan memory_get_usage () karena real_usage default adalah false.
jika Anda ingin mendapatkan memori yang dialokasikan oleh sistem tetapi tidak peduli berapa banyak yang sebenarnya digunakan, gunakan memory_get_usage (true);
sumber
<!-- Print CPU memory and load --> <?php $output = shell_exec('free'); $data = substr($output,111,19); echo $data; echo file_get_contents('/proc/loadavg'); $load = sys_getloadavg(); $res = implode("",$load); echo $res; ?>
sumber