PHP'de “Havuz için bellek ayrılamıyor” ya neden olan nedir?


133

Ara sıra, özellikle Wordpress gibi şişirilmiş bir uygulamada, bir sunucunun bellek ayırma sınırını aştım, ancak "Havuz için bellek ayırılamıyor" ve herhangi bir bilgiyi takip etmekte sorun yaşamadım.

Bunun ne anlama geldiğini bilen var mı? memory_limitBaşarısız olanı artırmayı denedim . Ayrıca uygulamada önemli bir değişiklik yapmadım. Bir gün sorun olmadı, ertesi gün bu hataya çarptım.

Yanıtlar:


90

Muhtemelen APC ile ilgilidir.

Bu sorunu yaşayan kişiler için lütfen .ini ayarlarını belirtin. Özellikle apc.mmap_file_mask ayarınız.

Dosya destekli mmap için aşağıdaki gibi bir şeye ayarlanmalıdır:

apc.mmap_file_mask=/tmp/apc.XXXXXX

Doğrudan / dev / zero'dan eşleştirmek için şunu kullanın:

apc.mmap_file_mask=/dev/zero

POSIX uyumlu paylaşılan bellek destekli mmap için şunları kullanın:

apc.mmap_file_mask=/apc.shm.XXXXXX

Teşekkürler! Tam da aradığım bağlantı buydu. Yardım için minnettarız!
jonathanatx

2
Bağlantılı iş parçacığındaki yorumlar da belgelediği için bu değişikliklerin sorunu çözmediğini buldum ...
Jonathan Day

3
Bu APC ayarı hakkında daha fazla bilgi: php.net/apc.configuration#ini.apc.mmap-file-mask
mikeytown2

2
Benim durumumda, hatadan kurtulmak için dosya destekli durumdan POSIX uyumlu hale geçmek zorunda kaldım.
Attila Fulop

4
Bu cevabın sorunu nasıl çözdüğünü anlamakta güçlük çekiyorum. Hata file_maskbu değerlerden biri olmadığında mı oluyor ? Bu değerlerden birine sahipsem ve hatayı alıyorsam, onu farklı bir değerle değiştirmem gerekir mi? Hangisi?
Jeff

125

0 TTL kullanılması, APC'nin bellek bittiğinde tüm önbelleği temizleyeceği anlamına gelir . Hata artık görünmüyor, ancak APC'yi çok daha az verimli hale getiriyor. Risk yok, sorun yok, "işimi yapmak istemiyorum" kararı. APC bu şekilde kullanılmak üzere tasarlanmamıştır. En çok erişilen sayfaların süresinin dolmaması için yeterince yüksek bir TTL seçmelisiniz. En iyisi, APC'nin önbelleği temizlemesine gerek kalmaması için yeterli bellek vermektir.

Ttl'nin nasıl kullanıldığını anlamak için kılavuzu okuyun: http://www.php.net/manual/en/apc.configuration.php#ini.apc.ttl

Çözüm, APC'ye ayrılan belleği artırmaktır. Apc.shm_size değerini artırarak bunu yapın.

APC, Paylaşılan Segment Belleğini kullanmak üzere derlenirse, işletim sisteminiz tarafından sınırlandırılırsınız. Her segment için sistem sınırınızı görmek için bu komutu yazın:

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

Daha fazla bellek ayırmak için apc.shm_segments parametresiyle segment sayısını artırmanız gerekir.

APC mmap bellek kullanıyorsa, o zaman sınırınız yoktur. Bellek miktarı yine aynı seçenek apc.shm_size ile tanımlanır.

Sunucuda yeterli bellek yoksa, daha az sıklıkla erişilen php dosyalarının önbelleğe alınmasını önlemek için filtreler seçeneğini kullanın.

Ama asla 0 TTL kullanmayın.

C33s'in dediği gibi, yapılandırmanızı kontrol etmek için apc.php kullanın. Dosyayı apc paketinden bir web klasörüne kopyalayın ve tarayıcıyı ona gösterin. Gerçekte neyin tahsis edildiğini ve nasıl kullanıldığını göreceksiniz. Grafikler saatler sonra sabit kalmalıdır, eğer her yenilemede tamamen değişiyorlarsa, bu, kurulumunuzun yanlış olduğu anlamına gelir (APC her şeyi temizliyor). APC'nin gerçekten bir güvenlik marjı olarak kullandığından% 20 daha fazla ram ayırın ve bunu düzenli olarak kontrol edin.

Yalnızca 32MB'ye izin vermenin varsayılanı gülünç derecede düşüktür. PHP, sunucular 64MB iken ve çoğu komut dosyası sayfa başına bir php dosyası kullandığında tasarlandı. Günümüzde Magento gibi çözümler 10.000'den fazla dosya gerektirmektedir (APC'de ~ 60 Mb). Yeterli belleğe izin vermelisiniz, böylece php dosyalarının çoğu her zaman önbelleğe alınır. Bu bir israf değildir, opcode'u dosya önbelleğinde karşılık gelen ham php'ye sahip olmaktansa ram içinde tutmak daha etkilidir. Günümüzde ayda 80 $ 'a kadar düşük bir fiyata 24 Gb belleğe sahip özel sunucular bulabiliyoruz, bu nedenle birkaç GB'den APC'ye izin vermekten çekinmeyin. 5Magento mağazalarını ve ~ 40 wordpress web sitesini barındıran bir sunucuya 24 GB'ın 2 GB'ını koydum, APC 1,2 GB kullanıyor. Magento kurulumu için 64MB, bazı eklentilere sahip bir Wordpress için 40MB sayın.

Ayrıca, aynı sunucuda geliştirme web siteleriniz varsa. Onları önbellekten hariç tutun.


2
Bu! Wordpress çalıştırıyorum ve 32M yeterli değildi. 64M'ye yükseltildi ve şimdi temiz. Apc.php kişilerini kontrol edin!
Dave Drager

İyi cevap! +1 Teşekkürler.
Kostanos

64M'ye yükseltmek için apc.shm_size = 64 eklemeniz gerekir, apc.shm_size = 64M'yi eklememelisiniz (gördüğüm çoğu örnekte sonunda bir M vardı) apc sürümümde çalışmadı (v3.1.3p1)
Patrick Forget

1
Önbellekte TTL'den daha uzun süre tutulan çok sayıda önbelleğe alınmış dosyanız olacağını varsayıyorsunuz. c33s önemli bir noktaya sahiptir. Her şeye yakın zamanda erişilmişse (diyelim ki, istediğiniz gibi her zaman erişilen önbelleğin% 70'ine sahipsiniz ve çok sayıda fazladan seyrek dosyanın aynı anda eklendiği büyük bir artış var), hatalar alacaksınız TTL saniye için atılır. Önbellek dolu ve APC'ye şikayet etmesi için bu girişleri temizlememesi gerektiğini söylediniz. 5 saatlik TTL'niz varsa, bu seyrek dosyaların süresinin dolmasını bekleyen 5 saatlik hatalarla sonuçlanırsınız.
Matthew Kolb

@MatthewKolb: APC'nin belleğinde tutabileceğinden daha fazla dosyanın önbelleğe alınmasına izin vermemelisiniz. Önbelleğe alınacak sık erişilmeyen dosyaları önceden bulmak için filtreleri kullanın.
bokan

36

benim için çözüm:

  • apc.ttl = 0
  • apc.shm_size = istediğiniz herhangi bir şey

başlangıcı düzenle

uyarı!

@bokan buraya bir uyarı eklemem gerektiğini belirtti.

0 ttl değerine sahipseniz, bu, önbelleğe alınan her öğenin hemen temizlenebileceği anlamına gelir. yani 2mb ve ttl gibi küçük bir önbellek boyutunuz varsa, bu apc'yi işe yaramaz hale getirir, çünkü önbellekteki verilerin her zaman üzerine yazılır.

ttl'nin düşürülmesi, yalnızca önbelleğin dolamayacağı, yalnızca değiştirilemeyen öğelerle dolacağı anlamına gelir.

bu nedenle ttl ve önbellek boyutu arasında iyi bir denge seçmeniz gerekir.

benim durumumda 1gb önbellek boyutuna sahiptim, bu yüzden benim için fazlasıyla yeterliydi.

düzenleme sonu

php 5.2.17 ile centos 5'te aynı sorunu yaşadı ve önbelleğe alınacak çok sayıda php dosyası varken önbellek boyutu küçükse ve ttl parametresi "yüksek" (7200 gibi) ise, önbelleğin oldukça hızlı dolduğunu fark etti ve apc kaldırabileceği hiçbir şey bulamaz çünkü önbellekteki tüm dosyalar hala ttl'ye sığar.

bellek boyutunu arttırmak sadece bir parça çözümdür, eğer önbellek dolarsa ve tüm dosyalar ttl içindeyse bu hatayı çalıştırmaya devam edersiniz.

bu yüzden benim çözümüm ttl'yi 0 olarak ayarlamaktı, bu yüzden apc önbelleği doldurur ve her zaman apc'nin yeni veriler için bir miktar bellek temizleme olasılığı vardır.

umarım yardımcı olur

düzenleme: ayrıca bkz .: http://pecl.php.net/bugs/bug.php?id=16966

indirmek http://pecl.php.net/get/APC apc.php özü ve çalıştırmak, güzel bir diyagramı kaç gibi önbellek kullanımı göz


2
Teşekkür ederim, bu yardımcı oldu. Saniyede yaklaşık bir düzine "Bellek ayrılamıyor" hatası alıyordum. Önbellek boyutumu ikiye katladım (32 ila 64 MB) ve ttl'yi 0'a düşürdüm. Bu, bu hataları tamamen ortadan kaldırdı.
nicktacular

1
Bu, sunucularımızdaki düzeltmeydi.
Justin

1
Bu benim için de sorunu çözmüş gibiydi.
anisoptera

1
ZWAMP kullanmak ve bu da hile yapmış gibi görünüyor. Teşekkürler.
WernerCD

10
Bu bir çözüm değil! Hata kaybolur ancak APC neredeyse devre dışı bırakılır. Hafıza her dolduğunda tüm önbelleği temizleyecektir. Brideau'nun bize verdiği kılavuzu okuyun. php.net/manual/en/apc.configuration.php#ini.apc.ttl.
bokan

7

Apc.php betiğini çalıştırmak, probleminizin ne olduğunu anlamanın anahtarıdır, IMO. Bu, önbelleğimizi doğru şekilde boyutlandırmamıza yardımcı oldu ve şimdilik sorunu çözmüş gibi görünüyor.


1
c33s'in dediği gibi: pecl.php.net/get/APC ekstresini indirin ve apc.php'yi çalıştırın, önbellek kullanımınızın nasıl göründüğüne dair güzel bir diyagramınız var
bokan

4

Benim gibi yeni başlayanlar için bu kaynaklar yardımcı oldu:

Yukarıdaki c33s tarafından önerilen değişiklikleri yapmak için apc.ini dosyasını bulmak ve önerilen miktarları ayarlamak: http://www.untwistedvortex.com/optimizing-tuning-apc-alternate-php-cache/

Apc.ttl'nin ne olduğunu anlamak: http://www.php.net/manual/en/apc.configuration.php#ini.apc.ttl

Apc.shm_size'nin ne olduğunu anlamak: http://www.php.net/manual/en/apc.configuration.php#ini.apc.shm-size


Teşekkürler, doğru çözümü belirttiniz. TTL'yi düşürmek, APC'yi devre dışı bırakmak gibidir.
bokan

4

Bokan'ın da belirttiği gibi, varsa hafızayı artırabilirsiniz ve TTL'yi 0'a ayarlamanın ne kadar karşı verimli olduğu konusunda haklı.

NotE: Sorunum için bu hatayı bu şekilde düzelttim. Bu, şeylerin bölünmesinden kaynaklanabilecek genel bir sorundur, bu nedenle yalnızca aşağıdaki hatayı takip edin ve bunun APC'ye yüklenmiş yinelenen PHP dosyalarının neden olduğunu düşünüyorsanız.

Yaşadığım sorun, PHP uygulamamın yeni bir sürümünü yayınladığım zamandı. Yani tüm .php dosyalarımı yenileriyle değiştirdim APC her iki sürümü de önbelleğe yükleyecektir.

Php dosyalarının iki sürümü için yeterli belleğe sahip olmadığım için APC'nin belleği doldu.

APC'ye belirli bir dosyanın değişip değişmediğini kontrol etmesini söyleyen apc.stat adında bir seçenek vardır ve eğer değiştirdiyse, bu genellikle geliştirme için uygundur, çünkü sürekli olarak değişiklik yaparsınız, ancak üretimde genellikle benimde olduğu gibi kapalıdır. durum - http://www.php.net/manual/en/apc.configuration.php#ini.apc.stat

Apc.stat'ı açmak, performans düşüşünden memnunsanız bu sorunu çözecektir.

Sorunum için bulduğum çözüm, proje sürümünün değişip değişmediğini kontrol etmek ve öyleyse önbelleği boşaltmak ve sayfayı yeniden yüklemek.

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);
}

2

Bu, çalışanlarımız için çalıştı (aynı sunucuda bir dizi Wordpress sitesi çalıştırıyor).

/Etc/php.d/apc.ini dosyasındaki bellek ayarları değiştirildi. 64M olarak ayarlandı, biz de onu ikiye katlayarak 128M'ye çıkardık.

apc.shm_size = 128M


1

İnternetlere bakıldığında çeşitli nedenler olabilir. Benim durumumda, hariç her şeyi varsayılan olarak bırakmak ...

apc.shm_size = 64M

... daha önce aldığım sayısız uyarıyı temizledi.


1

Bir OpenCart kurulumunu farklı bir sunucuya taşıdıktan sonra "Havuz için bellek ayrılamıyor" hatasını aldım. Ayrıca memory_limit'i yükseltmeyi denedim.

Hata mesajındaki dosyanın izinlerini apache'nin çalıştırdığı kullanıcının (apache, www-data, vb.) Yazma erişimine sahip olacak şekilde değiştirdikten sonra hata durdu. / Etc / group'u doğrudan değiştirmek (veya dosyaları 0777'ye dönüştürmek) yerine usermod'u kullandım:

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

Sonra değişikliğin etkili olması için apache'yi yeniden başlatmam gerekti:

apachectl restart

Veya

sudo /etc/init.d/httpd restart

Veya sisteminiz apache'yi yeniden başlatmak için ne kullanırsa kullansın.

Site paylaşılan barındırma üzerindeyse, dosya izinlerini bir FTP programıyla değiştirmeli veya barındırma sağlayıcısıyla iletişime geçmelisiniz?


1

Bu sorunu çözmek için apc.shm_size değerini tamsayı olarak ayarlayın apc.ini dosyanızı bulun (benim sistem apc.ini dosyasında /etc/php5/conf.d/apc.ini) ve şunu ayarlayın: apc.shm_size = 1000


1

sistemimde /usr/local/etc/php.ini (FreeBSD 9.1) içine apc.shm_size = 64M eklemek zorunda kaldım ve sonra apc.php'ye baktığımda (/ usr / local / share / doc / APC'den kopyaladım) /apc.php / usr / local / www / apache24 / data) önbellek boyutunun varsayılan 32M'den 64M'ye yükseldiğini ve artık büyük bir önbellek tam sayısı almadığımı buldum

referanslar: http://au1.php.net/manual/en/apc.configuration.php ayrıca Bokan'ın yorumlarını da okudu, çok yardımcı oldular


0

Önbelleğe Alınmış Dosya Boyutunuzu izleyin (apc pecl paketinden apc.php'yi kullanabilirsiniz) ve apc.shm_size'yi ihtiyaçlarınıza göre artırın.

Bu sorunu çözer.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.