Manakah dari fungsi php berikut yang dapat digunakan untuk mendapatkan penggunaan memori saat ini?

Faktanya, masalah konsumsi memori dapat dengan mudah menyebabkan crash, bug yang sulit ditemukan, dan bahkan membuka pintu untuk serangan Denial-of-Service.

Hal ini sangat penting di situs web dengan lalu lintas tinggi, di mana banyak eksekusi skrip bersamaan terjadi dan masalah terkait memori lebih mudah menyebabkan masalah

 

Sebelum pindah ke bagian selanjutnya, saya sarankan Anda melihat video singkat berikut, yang menjelaskan dengan baik bagaimana manajemen memori bekerja di PHP dan memberi Anda beberapa tips dasar untuk mengoptimalkan kode Anda

 

 

 

Beberapa jenis skrip PHP sangat berisiko konsumsi memori yang berlebihan

  • skrip yang sangat kompleks, terutama jika menyertakan loop bersarang;
  • skrip menggunakan sumber daya eksternal seperti file XML, kumpulan hasil basis data, dan koneksi jarak jauh;
  • skrip yang selalu aktif seperti daemon PHP

Tentu saja, masalah memori juga dapat terjadi pada skrip jenis lain

 

Tetapi bagaimana Anda bisa memeriksa berapa banyak memori yang digunakan skrip Anda?

Mudah

library PHP standar memberi Anda dua fungsi yang memberi Anda informasi yang tepat. memory_get_usage() dan memory_get_peak_usage() .

Mari kita lihat cara kerjanya.  

 

[tweet-mudah tweet="Tutorial (dengan contoh) tentang cara memeriksa penggunaan memori skrip PHP Anda" via="no" hashtags="PHP"]

 

 

   

 

memory_get_usage() mengembalikan jumlah byte yang digunakan oleh skrip saat fungsi dipanggil.

Demikian pula, memory_get_peak_usage() mengembalikan jumlah maksimum memori (sekali lagi, dalam byte) yang digunakan oleh skrip until the function is called.

Sebagai contoh

 

<?php $big_array = array(); for ($i = 0; $i < 1000000; $i++) { $big_array[] = $i; } echo 'After building the array.<br>'; print_mem(); unset($big_array); echo 'After unsetting the array.<br>'; print_mem(); function print_mem() { /* Currently used memory */ $mem_usage = memory_get_usage(); /* Peak memory usage */ $mem_peak = memory_get_peak_usage(); echo 'The script is now using: <strong>' . round($mem_usage / 1024) . 'KB</strong> of memory.<br>'; echo 'Peak usage: <strong>' . round($mem_peak / 1024) . 'KB</strong> of memory.<br><br>'; }

 

Di PC saya, saya mengerti

 

 

Seperti yang Anda lihat, setelah larik tidak disetel, penggunaan memori saat ini turun menjadi 370Kb, tetapi penggunaan puncaknya tetap sama

(Jika Anda ingin mempelajari cara menyiapkan lingkungan PHP lokal, lihat bab Memulai program pembelajaran PHP saya)

Kedua fungsi menggunakan argumen boolean opsional bernama $real_usage . Nilai standarnya salah.

Apa artinya dan kapan sebaiknya Anda menyetelnya ke true?

Ayo cari tahu

Apakah Anda ingin berbicara dengan saya dan pengembang lain tentang PHP dan pengembangan web? . Kafe Alex PHP

Sampai jumpa di sana 🙂

 

 

ARGUMEN $real_usage. BAGAIMANA CARA MENGGUNAKANNYA

Z

$real_usage adalah argumen boolean. Nilai defaultnya adalah false untuk memory_get_usage() dan memory_get_peak_usage().

Jika argumen ini disetel ke true, maka fungsi mengembalikan jumlah penuh dari  memori yang dialokasikan . instead of the memory actually used by the script.

Apa bedanya…?

 

 

Begini Cara kerjanya

Penerjemah PHP secara dinamis mengalokasikan memori untuk skrip. Memori ini dialokasikan dalam potongan, bagian kecil dari jumlah memori tetap.

Ketika semua memori yang dialokasikan telah digunakan oleh skrip, juru bahasa mengalokasikan potongan lain

Jadi

  • pertama , penafsir mencadangkan sebagian memori untuk digunakan skrip;
  • lalu  skrip secara bertahap mengisinya dengan datanya, sampai potongannya penuh;
  • jika skrip membutuhkan lebih banyak memori, juru bahasa mengalokasikan potongan memori lainnya;
  • ulang…

 

Oleh karena itu, jumlah yang dialokasikan  memori selalu sedikit lebih besar daripada jumlah digunakan< . memory (how much bigger depends on many factors, including the PHP configuration and the operating system settings).

 

Untuk inilah $real_usage digunakan

  • Jika $real_usage disetel ke  false (default) , maka fungsi mengembalikan yang digunakan .  only.
  • Jika $real_usage disetel ke true, maka fungsi mengembalikan seluruh  memori yang dialokasikan .

 

Contoh berikut menunjukkan bagaimana memori yang dialokasikan bertambah seiring dengan memori yang sebenarnya digunakan oleh skrip

 

<table align="center" valign="top"> <tr> <td>Used memory</td> <td>Allocated memory</td> <td>Difference</td> </tr> <?php $big_array = array(); for ($i = 0; $i < 100000; $i++) { $big_array[] = 'aaa' . $i; if (($i % 7000) == 0) { /* With $real_usage = false (the default value) */ $used_mem = round(memory_get_usage(false) / 1024); /* With $real_usage = true */ $alloc_mem = round(memory_get_usage(true) / 1024); echo '<tr><td style="color: green; border: 1px solid #888;">' . $used_mem . 'KB</td>'; echo '<td style="color: blue; border: 1px solid #888;">' . $alloc_mem . 'KB</td>'; echo '<td style="color: red; border: 1px solid #888;">' . ($alloc_mem - $used_mem) . 'KB</td></tr>'; } } _

 

Inilah hasilnya

 

Perhatikan bagaimana memori yang digunakan (kolom pertama) tumbuh secara bertahap, sedangkan memori yang dialokasikan (kolom kedua) tumbuh dalam potongan

 

Catatan

jika Anda mencoba menjalankan contoh ini dan mendapatkan hasil yang aneh, seperti memori yang dialokasikan lebih kecil dari memori yang digunakan, mungkin karena beberapa sistem caching

Cara untuk menghindari masalah tersebut adalah dengan memulai ulang server web tepat sebelum menjalankan skrip

 

Kapan Anda harus menyetel $real_usage ke true?

 

Inilah aturan praktisnya

jika Anda ingin melihat berapa banyak memori sistem yang digunakan skrip Anda, maka Anda harus menyetel . to true.

Mengapa?

Karena memori yang dialokasikan, meskipun tidak benar-benar digunakan oleh skrip, masih dicadangkan untuknya dan tidak tersedia untuk proses sistem lainnya

Dengan kata lain, ini adalah jumlah RAM sistem yang dicadangkan untuk proses PHP

 

Sebaliknya, jika Anda ingin membuat profil skrip PHP Anda , lebih baik biarkan false because you will see the memory usage in more detail.

Faktanya, dengan cara itu Anda dapat melihat berapa banyak memori yang digunakan oleh potongan kode tertentu terlepas dari berapa banyak memori yang tersedia untuk skrip secara keseluruhan

 

Mari kita lihat beberapa contoh cara melakukannya.  

 

 

 

CARA MEMANTAU LOOP

Di dalam struktur loop penggunaan memori yang berlebihan dapat menimbulkan masalah, terutama jika penggunaan ini terus bertambah setelah setiap iterasi loop.

Jika Anda ingin memastikan loop tidak menggunakan terlalu banyak memori, sebaiknya buat profilnya

Bagaimana kamu melakukannya?

 

Pertama-tama, Anda harus mencetak penggunaan memori sebelum dan sesudah pengulangan untuk memeriksa perbedaannya.

Jika Anda melihat bahwa penggunaan memori terlalu tinggi, Anda juga harus memeriksa bagian dalam loop itu sendiri

Parameter $real_usage sebaiknya dibiarkan false, karena Anda ingin profil your code in detail more than your whole script.

 

Ini juga berguna untuk melihat berapa banyak memori maksimum yang tersedia sedang digunakan

Skrip PHP hanya dapat menggunakan memori dalam jumlah tertentu. Nilai ini diatur dalam variabel memory_limit dari file php.ini. file ini (file konfigurasi utama PHP)

Anda dapat mengambil nilai tersebut dengan fungsi ini_get() , mengubahnya menjadi byte dan membandingkannya dengan penggunaan memori skrip

 

Ini sebuah contoh

 

<?php $mem_usage = memory_get_usage(); echo 'Memory usage before the loop: <strong>' . round($mem_usage / 1024) . 'KB</strong><br>'; /* Get the memory limit in bytes. */ $mem_limit = get_memory_limit(); echo 'Memory limit: <strong>' . round($mem_limit / 1048576) . 'MB</strong><br>'; $array = array(); for ($i = 0; $i < 100000; $i++) { $array[] = $i; /* Check the memory usage every 10000 iterations. */ if (($i % 10000) == 0) { $mem_usage = memory_get_usage(); $limit_perc = $mem_usage * 100 / $mem_limit; echo 'Memory usage after iteration ' . $i . ': <strong>' . round($mem_usage / 1024) . 'KB</strong> '; echo '(' . round($limit_perc) . '% of the available memory for the script)<br>'; } } $mem_usage = memory_get_usage(); echo 'Memory usage after the loop: <strong>' . round($mem_usage / 1024) . 'KB</strong><br>'; /* Parse the memory_limit variable from the php.ini file. */ function get_memory_limit() { $limit_string = ini_get('memory_limit'); $unit = strtolower(mb_substr($limit_string, -1 )); $bytes = intval(mb_substr($limit_string, 0, -1), 10); switch ($unit) { case 'k': $bytes *= 1024; break 1; case 'm': $bytes *= 1048576; break 1; case 'g': $bytes *= 1073741824; break 1; default: break 1; } return $bytes; }

 

   

CARA MEMANTAU DAEMON PHP

 

Daemon PHP adalah skrip perulangan yang tidak pernah berakhir

Mereka sangat berguna untuk tugas pemeliharaan dan pemantauan, seperti sistem pemberitahuan email otomatis dan operasi pemeliharaan

Sama seperti aplikasi selalu aktif, daemon PHP juga dapat mengalami kebocoran memori.

Praktik yang baik adalah memeriksa penggunaan memori di awal setiap putaran dan melakukan sesuatu jika ternyata terlalu tinggi

 

Misalnya, Anda dapat membunuh atau menghentikan sementara . send a notification email (you will see how to do it in the next chapter).

Untuk tujuan ini, sebaiknya atur $real_usage ke true, karena Anda sekarang lebih tertarik pada berapa banyak memori yang benar-benar digunakan .

 

Tentu saja, jika masalah memori terjadi, Anda perlu membuat profil skrip dengan hati-hati untuk melihat dari mana asal masalah (untuk itu, akan lebih baik membiarkan $real_usage menjadi false)

 

Sebagai contoh, mari kita lihat cara menghentikan daemon jika memori yang digunakan lebih dari 50Mb

 

<?php /* Remove the execution time limit */ set_time_limit(0); /* Iteration interval in seconds */ $sleep_time = 30; /* Memory limit (50Mb) */ $mem_limit = 52428800; $array = array(); $iteration = 0; while (TRUE) { $iteration++; /* Memory check */ if (memory_get_usage(true) >= $mem_limit) { echo 'Memory limit exceeded after iteration ' . strval($iteration); die(); } /* Sleep for the iteration interval */ sleep($sleep_time); for ($i = 0; $i < 500000; $i++) { $array[] = $i; } }

 

Anda juga dapat menghentikan daemon ketika penggunaan memorinya melebihi persentase tertentu dari penggunaan maksimum yang diperbolehkan

Untuk melakukan ini, Anda perlu membandingkan penggunaan memori dengan nilai memory_limit, seperti yang Anda lihat pada contoh loop sebelumnya

Inilah contohnya

 

<?php /* Remove the execution time limit. */ set_time_limit(0); /* Get the memory limit in bytes. */ $mem_limit = get_memory_limit(); /* Iteration interval in seconds. */ $sleep_time = 5; /* Max memory usage: 10% of the memory_limit. */ $mem_perc_limit = 20; $array = array(); $iteration = 0; while (TRUE) { $iteration++; /* Memory check. */ $mem_usage = memory_get_usage(true); $perc_usage = $mem_usage * 100 / $mem_limit; if ($perc_usage >= $mem_perc_limit) { echo 'Memory limit exceeded after iteration ' . $iteration . ' (' . round($perc_usage) . '%)'; die(); } /* Sleep for the iteration interval */ sleep($sleep_time); for ($i = 0; $i < 500000; $i++) { $array[] = $i; } } /* Parse the memory_limit variable from the php.ini file. */ function get_memory_limit() { $limit_string = ini_get('memory_limit'); $unit = strtolower(mb_substr($limit_string, -1 )); $bytes = intval(mb_substr($limit_string, 0, -1), 10); switch ($unit) { case 'k': $bytes *= 1024; break 1; case 'm': $bytes *= 1048576; break 1; case 'g': $bytes *= 1073741824; break 1; default: break 1; } return $bytes; } _

 

 

 

PANAS UNTUK MENDAPATKAN PEMBERITAHUAN EMAIL KETIKA MEMORY TERLALU BANYAK DIGUNAKAN

 

Terkadang, men-debug dan membuat profil penggunaan memori skrip PHP bisa jadi sulit

Tidak selalu mudah untuk mengambil output dari memory_get_usage() dan memory_get_peak_usage(), especially when the memory usage depends on the request string values and other factors.

 

Dalam beberapa kasus, masalah memori mungkin muncul hanya dalam keadaan tertentu atau hanya setelah beberapa waktu (terutama dalam daemon PHP)

Hanya mengulangi penggunaan memori tidak selalu cukup baik

Anda tidak bisa hanya menatap layar Anda menunggu kebocoran memori terjadi, bukan?

 

 

  Salah satu solusinya adalah log informasi penggunaan memori ke file log atau database.

Tetapi solusi ini juga tidak sempurna, karena Anda akan mendapatkan banyak log yang perlu Anda baca dan kelola

 

Solusi yang lebih cerdas adalah membuat PHP melakukan kerja keras

Alih-alih mencetak atau mencatat semuanya, cukup periksa apakah penggunaan memori terlalu tinggi

Jika tidak, lanjutkan eksekusi skrip. Jika tidak, kirimkan email pemberitahuan kepada Anda sendiri bersama dengan informasi debug yang berguna.

 

Prosedur sederhana ini menghilangkan kebutuhan Anda untuk secara aktif memeriksa skrip Anda

Faktanya, skrip itu sendiri akan memberi tahu Anda jika ada yang salah 😉

Jauh lebih baik, bukan?

 

Jadi, bagaimana ini bisa dilakukan dalam praktik?

 

Mari kembali ke contoh daemon

Sekarang, sebelum mematikan skrip ketika penggunaan memori terlalu tinggi, kami mengirim email agar kami tahu bahwa skrip ini telah dihentikan

Kami juga melampirkan file dengan jejak kembali debug dan satu dengan semua variabel yang ditentukan untuk memudahkan kami men-debug masalah

 

CATATAN. Anda perlu menginstal PHPMailer terlebih dahulu. Ikuti tutorial PHPMailer saya untuk mempelajari cara melakukannya.

 

Ini kodenya

<?php /* PHPMailer */ use \PHPMailer\PHPMailer\PHPMailer; use \PHPMailer\PHPMailer\Exception; require 'C:\xampp\htdocs\PHPMailer-master\src\Exception.php'; require 'C:\xampp\htdocs\PHPMailer-master\src\PHPMailer.php'; require 'C:\xampp\htdocs\PHPMailer-master\src\SMTP.php'; /* Remove the execution time limit */ set_time_limit(0); /* Iteration interval in seconds */ $sleep_time = 1; /* Memory limit (50Mb) */ $mem_limit = 52428800; $array = array(); $iteration = 0; while (TRUE) { $iteration++; /* Memory check */ if (memory_get_usage(true) >= $mem_limit) { send_debug_email(); echo 'This PHP script has been killed for using too much memory. An email has been sent.'; die(); } /* Sleep for the iteration interval */ sleep($sleep_time); for ($i = 0; $i < 500000; $i++) { $array[] = $i; } } function send_debug_email() { $mail = new PHPMailer(true); try { /* Source address */ $mail->setFrom('php@mysite'); /* Destination address */ $mail->addAddress('my_address@mysite'); /* Subject */ $mail->Subject = 'PHP script memory error'; /* Message */ $mail->Body = 'This PHP script has been killed for using too much memory.'; /* Add debug info as attachment */ $mail->addStringAttachment(print_r(debug_backtrace(), true), 'debug_backtrace.txt'); $mail->addStringAttachment(print_r(get_defined_vars(), true), 'defined_vars.txt'); /* Use SMTP. */ $mail->isSMTP(); /* SMTP server adrress. */ $mail->Host = 'mysmtp_server'; /* Use SMTP authentication. */ $mail->SMTPAuth = TRUE; /* Set the encryption system. */ $mail->SMTPSecure = 'tls'; /* SMTP authentication username. */ $mail->Username = 'smtp@mysite'; /* SMTP authentication password. */ $mail->Password = 'smtp_passwd'; /* Set the SMTP port. */ $mail->Port = 587; /* Send the mail. */ $mail->send(); } catch (Exception $e) { echo $e->errorMessage(); } catch (\Exception $e) { echo $e->getMessage(); } }

 

 

PERHATIAN. SUMBER DAYA

Ada satu masalah dengan memory_get_usage() dan memory_get_peak_usage()

mereka TIDAK memperhitungkan sumber daya .

Jenis resource PHP mencakup variabel yang ditangani oleh library eksternal atau sistem operasi, termasuk

  • koneksi jarak jauh (HTTP, FTP...)
  • File XML dibuat dengan SimpleXML
  • koneksi basis data
  • …dan banyak lagi

Memori sistem untuk jenis ini tidak ditangani oleh mesin inti PHP itu sendiri

Perpustakaan eksternal yang melakukan itu

Oleh karena itu, memory_get_[peak]_usage() tidak memasukkannya ke dalam hasilnya dan Anda perlu mengambilnya dengan cara lain

 

Posting dari drib tech ini dengan jelas menjelaskan situasi ini dan juga memberikan solusi

Dapatkan jumlah nyata dari memori yang dialokasikan oleh PHP

 

Solusi yang Anda temukan di posting di atas hanya berfungsi pada sistem Linux

Tapi jangan khawatir

jika Anda menggunakan Windows, Anda dapat menggunakan kode berikut yang bergantung pada alat jendela daftar tugas

 

<?php /* Load a big XML file to see the memory usage difference */ $xml_file = 'C:\xampp\htdocs\big_xml_file.xml'; $xml = simplexml_load_file($xml_file); if ($xml === false) { die('Unable to load and parse the XML file: "' . $xml_file . '"'); } /* Tasklist command to get info about the process ID running this script */ $cmd = 'tasklist /fi "pid eq ' . strval(getmypid()) . '"'; /* Get the output from tasklist */ $tasklist = trim(exec($cmd, $output)); /* Parse the output to get the memory usage value */ $mem_val = mb_strrchr($tasklist, ' ', TRUE); $mem_val = trim(mb_strrchr($mem_val, ' ', FALSE)); $mem_val = str_replace('.', '', $mem_val); echo 'Memory usage from <em>memory_get_usage()</em>: ' . round(memory_get_usage(true) / 1024) . 'KB<br>'; echo 'Memory usage from <em>tasklist</em>: ' . $mem_val . 'KB<br>'; _

 

 

KESIMPULAN

 

Sekarang Anda tahu mengapa penting untuk menjaga agar penggunaan memori skrip tetap terkendali, dan Anda tahu cara melakukannya

Anda mempelajari perbedaan antara memory_get_usage() dan memory_get_peak_usage() dan apa sebenarnya arti dari argumen $real_usage

Anda juga melihat bagaimana memasukkan jenis sumber daya eksternal dalam perhitungan, baik pada sistem Linux maupun Windows

Bagaimana cara menghitung penggunaan memori di PHP?

Untuk memeriksa penggunaan memori, PHP menyediakan fungsi bawaan memory_get_usage() . Fungsi ini mengembalikan jumlah memori yang dialokasikan ke skrip PHP. ** fungsi memory_get_usage() mengembalikan jumlah memori yang dialokasikan ke skrip PHP Anda dalam byte.

Manakah dari fungsi PHP berikut yang dapat digunakan untuk menghasilkan?

Solusi (Oleh Tim Examveda)

Manakah dari fungsi PHP berikut yang dapat digunakan untuk membangun fungsi yang menerima sejumlah argumen *?

Anda dapat menggunakan func_get_args() di dalam fungsi Anda untuk mengurai sejumlah parameter yang diteruskan.

Manakah dari fungsi PHP berikut yang dapat digunakan untuk membuat fungsi yang menerima sejumlah argumen Mcq?

Jawab. D) func_get_args() dapat menerima sejumlah parameter.

Postingan terbaru

LIHAT SEMUA