Pertanyaan memory_get_peak_usage () dengan "penggunaan nyata"


Jika itu real_usage argumen diatur ke true PHP DOCS mengatakan akan mendapatkan ukuran sebenarnya dari memori yang dialokasikan dari sistem. Jika itu false itu akan mendapatkan memori yang dilaporkan oleh emalloc()

Yang mana dari 2 opsi ini mengembalikan BPK maks. memori yang dialokasikan relatif terhadap nilai batas memori di php.ini?

Saya ingin tahu seberapa dekat naskah untuk mencapai batas itu.


75
2018-04-01 14:32


asal


Jawaban:


Ok, 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 nyata adalah memori yang dialokasikan dari sistem - yang tampaknya dialokasikan dalam ember yang lebih besar daripada yang saat ini dibutuhkan oleh skrip. (Saya kira karena alasan kinerja). Ini juga merupakan memori yang digunakan proses php.

Itu $real_usage = false penggunaan adalah penggunaan memori yang benar-benar Anda gunakan di skrip Anda, bukan jumlah sebenarnya dari memori yang dialokasikan oleh pengelola memori Zend.

Baca baca pertanyaan ini untuk informasi lebih lanjut.

Singkatnya: untuk mendapatkan seberapa dekat Anda dengan batas memori, gunakan $real_usage = true


105
2018-04-26 14:53



pengantar 

Kamu 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 dialokasikan 25MB penyimpanan untuk Anda tetapi itu tidak berarti itu adalah apa yang Anda gunakan saat ini.

Ini persis seperti yang dikatakan oleh dokumen PHP

Set ini ke TRUE untuk mendapatkan ukuran sebenarnya dari memori yang dialokasikan dari sistem. Jika tidak disetel atau FALSE hanya memori yang digunakan oleh emalloc () dilaporkan.

Kedua argumen akan mengembalikan memori yang dialokasikan relatif terhadap batas memori tetapi perbedaan utamanya adalah:

memory_get_usage(false) berikan memori yang digunakan oleh emalloc() sementara memory_get_usage(true) mengembalikan tonggak yang bisa menjadi demonstrasi di sini Toko Memori Mile

Saya ingin tahu seberapa dekat naskah untuk mencapai batas itu.

Itu akan mengambil beberapa matematika dan mungkin hanya bekerja di loop atau kasus penggunaan tertentu. Mengapa saya berkata 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 lingkaran atau fungsi rekursif, Anda dapat menggunakan penggunaan memori maksimum untuk memperkirakan secara aman saat daya ingat 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 Live 

Ini mungkin masih gagal

Ini mungkin gagal karena setelah if ($percentage > $peekPoint) {  ini masih tetap menambah untuk melakukan tugas tambahan dengan juga mengkonsumsi memori

        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.

Kesimpulan

Ini bukan solusi sempurna tetapi periksa memori pada interval dan jika melebihi mengintip (misalnya 90%) exit langsung dan tinggalkan barang mewah


29
2018-04-26 20:51



real_usage laporan palsu penggunaan skrip Anda bekas. Ini akan menjadi lebih akurat dari keduanya.

real_usage laporan benar memori dialokasikan ke skrip Anda. Ini akan menjadi lebih tinggi dari keduanya.

Saya mungkin akan menggunakan true jika saya mencoba membandingkan, karena skrip Anda tidak akan dialokasikan lebih dari batas memori, dan akan terus berjalan selama itu (ditambah semua skrip lain) tidak melebihi penggunaan itu.


7
2018-04-26 13:57



sesuai PHP memory_get_usage

real_usage

Setel ini ke TRUE untuk mendapatkan total memori yang dialokasikan dari sistem, termasuk halaman yang tidak digunakan. Jika tidak disetel atau FALSE hanya memori yang digunakan yang dilaporkan.

jadi untuk mendapatkan memori yang digunakan oleh skrip Anda, Anda harus menggunakan memory_get_usage () sebagai default real_usage yang salah.

jika Anda ingin mendapatkan memori yang dialokasikan oleh sistem tetapi tidak peduli seberapa banyak yang sebenarnya digunakan, gunakan memory_get_usage (true);


1
2017-11-01 13:02