Saya memiliki banyak sistem klien titik penjualan (POS) yang secara berkala mengirim data penjualan baru ke satu database terpusat, yang menyimpan data ke dalam satu database besar untuk pembuatan laporan.
POS klien didasarkan pada PHPPOS, dan saya telah mengimplementasikan modul yang menggunakan pustaka XML-RPC standar untuk mengirim data penjualan ke layanan. Sistem server dibangun di atas CodeIgniter, dan menggunakan pustaka XML-RPC dan XML-RPCS untuk komponen layanan web. Setiap kali saya mengirim banyak data penjualan (sedikitnya 50 baris dari tabel penjualan, dan baris individual dari sales_item yang berkaitan dengan setiap item dalam penjualan) saya mendapatkan kesalahan berikut:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 54 bytes)
128M adalah nilai default php.ini
, tapi saya berasumsi itu adalah angka yang sangat besar untuk dipecahkan. Bahkan, saya bahkan telah mencoba mengatur nilai ini ke 1024M, dan yang diperlukan hanyalah waktu lebih lama untuk melakukan kesalahan.
Adapun langkah-langkah yang telah saya ambil, saya sudah mencoba menonaktifkan semua pemrosesan di sisi server, dan telah memasang itu untuk mengembalikan respons kalengan terlepas dari input. Namun, saya percaya masalahnya terletak pada pengiriman data yang sebenarnya. Saya bahkan sudah mencoba menonaktifkan waktu eksekusi skrip maksimum untuk PHP, dan itu masih error.
sumber
ini_set('memory_limit', '256M');
Jawaban:
Mengubah
memory_limit
olehini_set('memory_limit', '-1');
adalah tidak solusi yang tepat. Tolong jangan lakukan itu.Kode PHP Anda mungkin mengalami kebocoran memori di suatu tempat dan Anda memberi tahu server untuk hanya menggunakan semua memori yang diinginkan. Anda tidak akan memperbaiki masalah sama sekali. Jika Anda memantau server Anda, Anda akan melihat bahwa sekarang mungkin menggunakan sebagian besar RAM dan bahkan menukar ke disk.
Anda mungkin harus mencoba melacak kode yang menyinggung dalam kode Anda dan memperbaikinya.
sumber
-1
bisa berguna hanya di lingkungan dev untuk tujuan pengujian.ini_set('memory_limit', '-1');
mengabaikan batas memori PHP default .sumber
-1
adalah nilai yang dipahami oleh PHP sebagai tidak terbatas dalam konteks ini.Cara yang benar adalah mengedit
php.ini
file Anda . Editmemory_limit
nilai keinginan Anda.Seperti dari pertanyaan Anda,
128M
(yang merupakan batas default) telah terlampaui, jadi ada sesuatu yang salah dengan kode Anda karena tidak boleh terlalu banyak.Jika Anda tahu mengapa dibutuhkan sebanyak itu dan Anda ingin mengizinkannya ditetapkan
memory_limit = 512M
atau lebih tinggi dan Anda harus baik.sumber
Alokasi memori untuk PHP dapat disesuaikan secara permanen, atau sementara.
Secara permanen
Anda dapat mengubah secara permanen alokasi memori PHP dengan dua cara.
Jika Anda memiliki akses ke
php.ini
file Anda, Anda dapat mengedit nilai untukmemory_limit
nilai keinginan Anda.Jika Anda tidak memiliki akses ke
php.ini
file Anda (dan webhost Anda mengizinkannya), Anda dapat mengganti alokasi memori melalui.htaccess
file Anda . Tambahkanphp_value memory_limit 128M
(atau apa pun alokasi yang Anda inginkan).Sementara
Anda dapat menyesuaikan alokasi memori dengan cepat dari dalam file PHP. Anda cukup memiliki kode
ini_set('memory_limit', '128M');
(atau apa pun alokasi yang Anda inginkan). Anda dapat menghapus batas memori (meskipun mesin atau batas instance mungkin masih berlaku) dengan mengatur nilai ke "-1".sumber
Sangat mudah untuk mendapatkan kebocoran memori dalam skrip PHP - terutama jika Anda menggunakan abstraksi, seperti ORM. Coba gunakan Xdebug untuk profil skrip Anda dan cari tahu di mana semua memori itu pergi.
sumber
Ketika menambahkan 22,5 juta catatan ke dalam array dengan array_push saya terus mendapatkan "kehabisan memori" kesalahan fatal di sekitar 20 juta catatan menggunakan
4G
sebagai batas memori dalam file php.ini. Untuk memperbaikinya, saya menambahkan pernyataandi bagian atas file. Sekarang semuanya bekerja dengan baik. Saya tidak tahu apakah PHP memiliki kebocoran memori. Itu bukan pekerjaan saya, saya juga tidak peduli. Saya hanya harus menyelesaikan pekerjaan saya, dan ini berhasil.
Program ini sangat sederhana:
Kesalahan fatal menunjuk ke baris 3 sampai saya meningkatkan batas memori, yang menghilangkan kesalahan.
sumber
ini_set('memory_limit', '8192M');
?Saya terus mendapatkan kesalahan ini, bahkan dengan
memory_limit
set inphp.ini
, dan nilai pembacaan dengan benarphpinfo()
.Dengan mengubahnya dari ini:
Untuk ini:
Ini memperbaiki masalah di PHP 7.
sumber
Ketika Anda melihat kesalahan di atas - terutama jika
(tried to allocate __ bytes)
nilainya rendah, itu bisa menjadi indikator loop tak terbatas, seperti fungsi yang menyebut dirinya sendiri tanpa jalan keluar:sumber
Setelah mengaktifkan dua baris ini, mulai bekerja:
sumber
Anda dapat memperbaiki ini dengan benar dengan mengubah
memory_limit
fastcgi / fpm:Ubah memori, seperti dari 128 menjadi 512, lihat di bawah
untuk
sumber
Direktori root situs Anda:
sumber
Ubah batas memori dalam file php.ini dan restart Apache. Setelah restart, jalankan phpinfo (); berfungsi dari file PHP apa pun untuk
memory_limit
konfirmasi perubahan.Batas memori -1 berarti tidak ada batas memori yang ditetapkan. Sekarang sudah maksimal.
sumber
Untuk pengguna Drupal, ini jawaban Chris Lane dari:
bekerja tetapi kita harus meletakkannya tepat setelah pembukaan
beri tag pada file index.php di direktori root situs Anda.
sumber
Di Drupal 7, Anda dapat mengubah batas memori dalam file settings.php yang terletak di situs / folder default Anda. Sekitar baris 260, Anda akan melihat ini:
Bahkan jika pengaturan php.ini Anda cukup tinggi, Anda tidak akan dapat mengkonsumsi lebih dari 128 MB jika ini tidak diatur dalam file Drupal settings.php Anda.
sumber
Daripada mengubah
memory_limit
nilai dalamphp.ini
file Anda , jika ada bagian dari kode Anda yang dapat menggunakan banyak memori, Anda bisa menghapusmemory_limit
sebelum bagian itu berjalan, dan kemudian menggantinya setelah itu.sumber
PHP 5.3+ memungkinkan Anda untuk mengubah batas memori dengan menempatkan
.user.ini
file dipublic_html
folder. Cukup buat file di atas dan ketik baris berikut di dalamnya:Beberapa host cPanel hanya menerima metode ini.
sumber
Halaman rusak?
(Ini terjadi ketika MySQL harus query baris besar. Secara default,
memory_limit
diatur ke kecil, yang lebih aman untuk perangkat keras.)Anda dapat memeriksa status memori yang ada sistem Anda, sebelum menambah
php.ini
:Di sini saya telah meningkatkannya sebagai berikut dan kemudian lakukan
service httpd restart
untuk memperbaiki masalah halaman macet.sumber
free -m
perintah untuk memutuskan memory_limit baru?Cukup tambahkan
ini_set('memory_limit', '-1');
baris di bagian atas halaman web Anda.Dan Anda dapat mengatur memori Anda sesuai kebutuhan Anda di tempat -1, ke
16M
, dll.sumber
Bagi mereka yang menggaruk-garuk kepala untuk mencari tahu mengapa di bumi fungsi kecil ini harus menyebabkan kebocoran memori, kadang-kadang karena kesalahan kecil, fungsi mulai memanggil dirinya sendiri secara rekursif selamanya.
Misalnya, kelas proksi yang memiliki nama yang sama untuk fungsi objek yang akan mem-proksi itu.
Kadang-kadang Anda mungkin lupa untuk membawa anggota actualObjec yang kecil itu dan karena proxy sebenarnya memiliki
doSomething
metode itu, PHP tidak akan memberi Anda kesalahan dan untuk kelas besar, itu bisa disembunyikan dari mata selama beberapa menit untuk mencari tahu mengapa bocor memori.sumber
die('here')
kode Anda dan memindahkan pernyataan itu untuk melihat di mana rekursi dimulai.Saya memiliki kesalahan di bawah ini saat menjalankan dataset yang lebih kecil dari yang pernah bekerja sebelumnya.
Ketika pencarian kesalahan membawa saya ke sini, saya pikir saya akan menyebutkan bahwa itu tidak selalu merupakan solusi teknis dalam jawaban sebelumnya, tetapi sesuatu yang lebih sederhana. Dalam kasus saya itu adalah Firefox. Sebelum saya menjalankan program itu sudah menggunakan 1.157 MB.
Ternyata saya telah menonton video 50 menit sedikit demi sedikit selama beberapa hari dan itu mengacaukan segalanya. Ini semacam perbaikan yang diperbaiki oleh para ahli bahkan tanpa dipikirkan, tetapi bagi orang-orang seperti saya, ada baiknya diingat.
sumber
Menjalankan skrip seperti ini (cron case misalnya):
php5 /pathToScript/info.php
menghasilkan kesalahan yang sama.Cara yang benar:
php5 -cli /pathToScript/info.php
sumber
Jika Anda menjalankan VPS bertenaga WHM (virtual private server) Anda mungkin menemukan bahwa Anda tidak memiliki izin untuk mengedit PHP.INI secara langsung; sistem harus melakukannya. Di panel kontrol host WHM, buka Konfigurasi Layanan → Editor Konfigurasi PHP dan ubah
memory_limit
:sumber
Saya merasa berguna saat memasukkan atau membutuhkan
_dbconnection.php_
dan_functions.php
dalam file yang benar-benar diproses, daripada termasuk dalam header. Yang termasuk dalam dirinya sendiri.Jadi, jika header dan footer Anda disertakan, cukup sertakan semua file fungsional Anda sebelum header dimasukkan.
sumber
Menggunakan
yield
mungkin menjadi solusi juga. Lihat Sintaks generator .Alih-alih mengubah
PHP.ini
file untuk penyimpanan memori yang lebih besar, kadang-kadang menerapkanyield
loop di dalam mungkin memperbaiki masalah. Apa yang dilakukan adalah alih-alih membuang semua data sekaligus, ia membacanya satu per satu, menghemat banyak penggunaan memori.sumber
PHP.ini
? Bukanphp.ini
?Kesalahan ini kadang-kadang disebabkan oleh bug dalam kode PHP yang menyebabkan rekursi yang melibatkan penanganan pengecualian dan kemungkinan operasi lainnya. Sayangnya, saya belum bisa membuat contoh kecil.
Dalam kasus ini, yang telah terjadi pada saya beberapa kali,
set_time_limit
gagal, dan browser terus berusaha memuat output PHP, baik dengan infinite loop atau dengan pesan kesalahan fatal yang menjadi topik pertanyaan ini.Dengan mengurangi ukuran alokasi yang diizinkan dengan menambahkan
mendekati awal kode Anda, Anda harus dapat mencegah kesalahan fatal.
Maka Anda mungkin dibiarkan dengan program yang berakhir, tetapi masih sulit untuk debug.
Pada titik ini masukkan
BreakLoop()
panggilan di dalam program Anda untuk mendapatkan kontrol dan mencari tahu apa loop atau rekursi dalam program Anda yang menyebabkan masalah.Definisi BreakLoop adalah sebagai berikut:
Argumen $ LoopSite dapat menjadi nama fungsi dalam kode Anda. Ini tidak benar-benar diperlukan, karena pesan kesalahan yang Anda dapatkan akan mengarahkan Anda ke baris yang berisi panggilan BreakLoop ().
sumber
Dalam kasus saya itu adalah masalah singkat dengan cara fungsi ditulis. Kebocoran memori dapat disebabkan oleh menetapkan nilai baru ke variabel input fungsi, misalnya:
sumber
Ketika saya menghapus baris berikut dari kode saya, semua berfungsi dengan baik!
Baris-baris ini termasuk dalam setiap file yang saya jalankan. Saat menjalankan file satu per satu, semuanya bekerja dengan baik, tetapi ketika menjalankan semua file bersama-sama saya mendapatkan masalah kebocoran memori. Entah bagaimana "include_once" tidak termasuk hal sekali, atau saya melakukan sesuatu yang salah ...
sumber
set_include_path(get_include_path() . get_include_path().'/phpseclib');
Ini akan menambahkan path '/ phpseclib' satu kali untuk setiap file yang memiliki baris ... sehingga ia dapat menambahkannya berkali-kali! Saya sarankan meletakkannya di file pengaturan daninclude_once
file pengaturan.