Apa yang menyebabkan "Tidak dapat mengalokasikan memori untuk kumpulan" di PHP?

133

Saya kadang-kadang menjalankan terhadap batas alokasi memori server, terutama dengan aplikasi kembung seperti Wordpress, tetapi tidak pernah menemukan "Tidak dapat mengalokasikan memori untuk kumpulan" dan mengalami kesulitan melacak informasi apa pun.

Adakah yang tahu apa artinya ini? Saya sudah mencoba meningkatkan memory_limittanpa keberhasilan. Saya juga belum membuat perubahan signifikan pada aplikasi. Suatu hari tidak ada masalah, hari berikutnya saya menemukan kesalahan ini.

Jonathanatx
sumber

Jawaban:

90

Mungkin terkait APC.

Untuk orang-orang yang mengalami masalah ini, harap tentukan pengaturan .ini Anda. Khususnya pengaturan apc.mmap_file_mask Anda.

Untuk mmap yang didukung file, harus diatur ke sesuatu seperti:

apc.mmap_file_mask=/tmp/apc.XXXXXX

Untuk mmap langsung dari / dev / zero, gunakan:

apc.mmap_file_mask=/dev/zero

Untuk mmap yang didukung oleh POSIX yang didukung memori, gunakan:

apc.mmap_file_mask=/apc.shm.XXXXXX
Frankie
sumber
Terima kasih! Itulah tautan yang saya cari. Hargai bantuannya!
jonathanatx
2
Saya telah menemukan bahwa perubahan ini tidak memperbaiki masalah, karena komentar pada utas tertaut juga mendokumentasikan ...
Jonathan Day
3
Info lebih lanjut untuk pengaturan APC ini: php.net/apc.configuration#ini.apc.mmap-file-mask
mikeytown2
2
Dalam kasus saya, saya harus mengubah dari yang didukung file ke POSIX-compliant untuk menghilangkan kesalahan.
Attila Fulop
4
Saya bingung untuk memahami bagaimana jawaban ini memecahkan masalah. Apakah kesalahan terjadi ketika file_maskbukan salah satu dari nilai-nilai ini? Jika saya memiliki salah satu dari nilai-nilai ini dan saya mendapatkan kesalahan, apakah saya perlu mengubahnya ke yang lain? Yang mana?
Jeff
125

Menggunakan TTL 0 berarti bahwa APC akan membersihkan semua cache saat kehabisan memori. Kesalahan tidak muncul lagi tetapi itu membuat APC jauh lebih efisien. Ini bukan risiko, tidak ada masalah, keputusan "Saya tidak ingin melakukan pekerjaan saya". APC tidak dimaksudkan untuk digunakan seperti itu. Anda harus memilih TTL yang cukup tinggi sehingga halaman yang paling banyak diakses tidak akan kedaluwarsa. Yang terbaik adalah memberikan memori yang cukup sehingga APC tidak perlu membersihkan cache.

Cukup baca manual untuk memahami bagaimana ttl digunakan: http://www.php.net/manual/en/apc.configuration.php#ini.apc.ttl

Solusinya adalah menambah memori yang dialokasikan untuk APC. Lakukan ini dengan meningkatkan apc.shm_size.

Jika APC dikompilasi untuk menggunakan Memori Segmen Bersama, Anda akan dibatasi oleh sistem operasi Anda. Ketik perintah ini untuk melihat batas sistem Anda untuk setiap segmen:

sysctl -a | grep -E "shmall|shmmax"

Untuk mengalokasikan lebih banyak memori, Anda harus menambah jumlah segmen dengan parameter apc.shm_segments.

Jika APC menggunakan memori mmap maka Anda tidak memiliki batas. Jumlah memori masih ditentukan oleh opsi apc.shm_size yang sama.

Jika tidak ada cukup memori di server, maka gunakan opsi filter untuk mencegah cache file yang jarang diakses diakses.

Tapi jangan pernah gunakan TTL 0.

Seperti c33s katakan, gunakan apc.php untuk memeriksa konfigurasi Anda. Salin file dari paket apc ke folder web dan arahkan browser ke sana. Anda akan melihat apa yang benar-benar dialokasikan dan bagaimana menggunakannya. Grafik harus tetap stabil setelah jam, jika mereka sepenuhnya berubah pada setiap refresh, maka itu berarti bahwa pengaturan Anda salah (APC membilas semuanya). Alokasikan ram 20% lebih banyak dari apa yang benar-benar digunakan APC sebagai margin keamanan, dan periksa secara teratur.

Default hanya mengizinkan 32MB sangat rendah. PHP dirancang ketika server 64MB dan sebagian besar skrip menggunakan satu file php per halaman. Saat ini solusi seperti Magento memerlukan lebih dari 10k file (~ 60Mb di APC). Anda harus mengizinkan memori yang cukup sehingga sebagian besar file php selalu di-cache. Ini bukan pemborosan, lebih efisien untuk menyimpan opcode di ram daripada memiliki php mentah yang sesuai dalam cache file. Saat ini kita dapat menemukan server khusus dengan memori 24Gb untuk $ 80 / bulan, jadi jangan ragu untuk mengizinkan beberapa GB untuk APC. Saya mengeluarkan 2GB dari 24GB di server yang menampung 5 toko Magento dan ~ 40 situs web wordpress, APC menggunakan 1.2GB. Hitung 64MB untuk instalasi Magento, 40MB untuk Wordpress dengan beberapa plugin.

Juga, jika Anda memiliki situs web development di server yang sama. Kecualikan mereka dari cache.

bokan
sumber
2
Ini! Saya menjalankan Wordpress dan 32 juta tidak cukup. Hingga 64M dan sekarang di bersihkan. Periksa orang-orang apc.php!
Dave Drager
Jawaban yang bagus! +1 Terima kasih.
Kostanos
Untuk meningkatkan ke 64M Anda perlu menambahkan apc.shm_size = 64 dan tidak apc.shm_size = 64M (kebanyakan contoh saya telah melihat M pada akhirnya) Tidak berfungsi pada versi apc saya (v3.1.3p1)
Patrick Lupakan
1
Anda mengasumsikan bahwa Anda akan memiliki banyak file dalam cache yang telah ada dalam cache lebih lama dari TTL. C33 memiliki poin penting. Jika semuanya baru-baru ini diakses (katakanlah Anda memiliki 70% dari cache yang dapat diakses sepanjang waktu seperti yang Anda inginkan dan memiliki lonjakan besar di mana banyak file tambahan jarang ditambahkan sekaligus), Anda akan mendapatkan kesalahan dilempar selama TTL detik. Tembolok penuh, dan Anda memberi tahu APC bahwa tidak boleh menghapus entri ini sehingga komplain. Jika Anda memiliki TTL selama 5 jam, Anda berakhir dengan kesalahan senilai 5 jam menunggu file yang jarang tersebut berakhir.
Matius Kolb
@ MatthewKolb: Anda seharusnya tidak mengizinkan caching lebih banyak file daripada yang dapat disimpan oleh APC dalam memorinya. Gunakan filter untuk mencegah file-file yang tidak diakses untuk di-cache.
bokan
36

solusi untuk saya:

  • apc.ttl = 0
  • apc.shm_size = apa pun yang Anda inginkan

sunting mulai

peringatan!

@bokan memberi tahu saya bahwa saya harus menambahkan peringatan di sini.

jika Anda memiliki ttl 0 ini berarti setiap item yang di-cache dapat dibersihkan segera. jadi jika Anda memiliki ukuran cache yang kecil seperti 2mb dan ttl 0 ini akan membuat apc tidak berguna, karena data dalam cache selalu ditimpa.

menurunkan ttl berarti hanya bahwa cache tidak dapat menjadi penuh, hanya dengan item yang tidak dapat diganti.

jadi Anda harus memilih keseimbangan yang baik antara ttl dan ukuran cache.

dalam kasus saya, saya memiliki ukuran cache 1GB, jadi itu lebih dari cukup untuk saya.

edit akhir

memiliki masalah yang sama pada centos 5 dengan php 5.2.17 dan memperhatikan bahwa jika ukuran cache kecil dan parameter ttl "tinggi" (seperti 7200) sementara memiliki banyak file php untuk di-cache, maka cache terisi cukup cepat dan apc tidak menemukan apa pun yang dapat dihapus karena semua file dalam cache masih muat di ttl.

meningkatkan ukuran memori hanya merupakan bagian solusi, Anda masih menjalankan kesalahan ini jika Anda mengisi cache dan semua file berada dalam ttl.

jadi solusi saya adalah mengatur ttl ke 0, jadi apc mengisi cache dan ada kemungkinan untuk apc menghapus beberapa memori untuk data baru.

berharap itu bisa membantu

sunting: lihat juga: http://pecl.php.net/bugs/bug.php?id=16966

unduh http://pecl.php.net/get/APC ekstrak dan jalankan apc.php, di sana Anda memiliki diagram yang bagus tentang bagaimana penggunaan cache Anda terlihat seperti

c33s
sumber
2
Terima kasih, ini memang membantu. Saya mendapatkan sekitar selusin kesalahan "Tidak dapat mengalokasikan memori" per detik. Saya menggandakan ukuran cache saya (32 hingga 64 MB) dan menjatuhkan ttl ke 0. Itu sepenuhnya menghapus kesalahan ini.
nicktacular
1
Ini adalah perbaikan pada server kami.
Justin
1
Ini sepertinya memperbaiki masalah bagi saya juga.
anisoptera
1
Menggunakan ZWAMP dan ini tampaknya telah melakukan trik juga. Terima kasih.
WernerCD
10
Ini bukan solusi! Kesalahan menghilang tetapi APC akan hampir dinonaktifkan. Ini akan membersihkan semua cache setiap kali memori penuh. Baca saja petunjuk yang diberikan Brideau kepada kami. php.net/manual/en/apc.configuration.php#ini.apc.ttl.
bokan
7

Menjalankan skrip apc.php adalah kunci untuk memahami apa masalah Anda, IMO. Ini membantu kami mengukur cache dengan benar dan untuk saat ini, tampaknya telah menyelesaikan masalah.

Brice D
sumber
1
seperti yang dikatakan c33s: unduh pecl.php.net/get/APC ekstrak dan jalankan apc.php, di sana Anda memiliki diagram yang bagus seperti apa tampilan penggunaan cache Anda
bokan
4

Untuk pemula seperti saya, sumber daya ini membantu:

Menemukan file apc.ini untuk membuat perubahan yang direkomendasikan oleh c33s di atas, dan mengatur jumlah yang disarankan: http://www.untwistedvortex.com/optimizing-tuning-apc-alternate-php-cache/

Memahami apa itu apc.ttl adalah: http://www.php.net/manual/en/apc.configuration.php#ini.apc.ttl

Memahami apa itu apc.shm_size adalah: http://www.php.net/manual/en/apc.configuration.php#ini.apc.shm-size

Brideau
sumber
Terima kasih, Anda menunjukkan solusi yang tepat. Menurunkan TTL sama seperti menonaktifkan APC.
bokan
4

Seperti yang disebutkan oleh Bokan, Anda dapat menaikkan memori jika tersedia, dan ia benar tentang bagaimana pengaturan kontra produktif TTL ke 0 adalah.

Catatan: Inilah cara saya memperbaiki kesalahan ini untuk masalah khusus saya. Ini adalah masalah umum yang dapat disebabkan oleh banyak hal jadi ikuti saja di bawah ini jika Anda mendapatkan kesalahan dan Anda pikir itu disebabkan oleh duplikat file PHP yang sedang dimuat ke APC.

Masalah yang saya alami adalah ketika saya merilis versi baru aplikasi PHP saya. Yaitu mengganti semua file .php saya dengan yang baru APC akan memuat kedua versi ke dalam cache.

Karena saya tidak punya cukup memori untuk dua versi file php, APC akan kehabisan memori.

Ada opsi yang disebut apc.stat untuk memberitahu APC untuk memeriksa apakah file tertentu telah berubah dan jika begitu ganti itu, ini biasanya ok untuk pengembangan karena Anda terus membuat perubahan namun pada produksi biasanya dimatikan seperti di dalam saya case - http://www.php.net/manual/en/apc.configuration.php#ini.apc.stat

Mengaktifkan apc.stat akan memperbaiki masalah ini jika Anda setuju dengan hit kinerja.

Solusi yang saya temukan untuk masalah saya adalah memeriksa apakah versi proyek telah berubah dan jika demikian kosongkan cache dan muat ulang halaman.

define('PROJECT_VERSION', '0.28'); 

if(apc_exists('MY_APP_VERSION') ){

    if(apc_fetch('MY_APP_VERSION') != PROJECT_VERSION){
        apc_clear_cache();
        apc_store ('MY_APP_VERSION', PROJECT_VERSION);
        header('Location: ' . 'http'.(empty($_SERVER['HTTPS'])?'':'s').'://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']);
        exit;  
    }

}else{
    apc_store ('MY_APP_VERSION', PROJECT_VERSION);
}
Jase Whatson
sumber
2

Ini bekerja untuk orang-orang kami (menjalankan banyak situs Wordpress di server yang sama).

Mengubah pengaturan memori dalam file /etc/php.d/apc.ini. Itu diatur ke 64M, jadi kami menggandakannya menjadi 128M.

apc.shm_size = 128M

Peter Drinnan
sumber
1

Melihat internet mungkin ada berbagai penyebab. Dalam kasus saya membiarkan semuanya default kecuali ...

apc.shm_size = 64M

... membersihkan peringatan yang tak terhitung jumlahnya yang saya dapatkan sebelumnya.

Leo
sumber
1

Saya menerima kesalahan "Tidak dapat mengalokasikan memori untuk kumpulan" setelah memindahkan instalasi OpenCart ke server yang berbeda. Saya juga mencoba menaikkan memory_limit.

Kesalahan berhenti setelah saya mengubah izin file dalam pesan kesalahan agar memiliki akses tulis oleh pengguna yang dijalankan sebagai apache (apache, www-data, dll.). Alih-alih memodifikasi / etc / group secara langsung (atau chmod-ing file ke 0777), saya menggunakan usermod:

usermod -a -G vhost-user-group apache-user

Kemudian saya harus memulai kembali apache agar perubahan diterapkan:

apachectl restart

Atau

sudo /etc/init.d/httpd restart

Atau apa pun yang digunakan sistem Anda untuk memulai ulang apache.

Jika situs tersebut menggunakan hosting bersama, mungkin Anda harus mengubah izin file dengan program FTP, atau menghubungi penyedia hosting?

Brent Self
sumber
1

Untuk mengatasi masalah ini, tetapkan nilai untuk apc.shm_size sebagai integer Temukan file apc.ini Anda (di lokasi file sistem apc.ini saya /etc/php5/conf.d/apc.ini) dan set: apc.shm_size = 1000

Bialy7
sumber
1

pada sistem saya, saya harus memasukkan apc.shm_size = 64M ke /usr/local/etc/php.ini (FreeBSD 9.1) lalu ketika saya melihat apc.php (yang saya salin dari / usr / local / share / doc / APC) /apc.php ke / usr / local / www / apache24 / data) saya menemukan bahwa ukuran cache telah meningkat dari standar 32M ke 64M dan saya tidak lagi mendapatkan jumlah cache penuh yang besar

referensi: http://au1.php.net/manual/en/apc.configuration.php juga membaca komentar Bokan, mereka sangat membantu

andrew
sumber
0

Pantau Ukuran File Cached Anda (Anda dapat menggunakan apc.php dari paket apc pecl) dan tingkatkan apc.shm_size sesuai dengan kebutuhan Anda.

Ini menyelesaikan masalah.

lazcorp
sumber