Python alt işlemi.Popen "OSError: [Errno 12] Bellek ayrılamıyor"


114

Not: Bu soru başlangıçta burada sorulmuştu ancak kabul edilebilir bir cevap bulunamasa da ödül süresi doldu. Orijinal soruda verilen tüm detaylar dahil olmak üzere bu soruyu tekrar soruyorum.

Bir python betiği, zamanlama modülünü kullanarak her 60 saniyede bir sınıf işlevleri kümesini çalıştırır :

# sc is a sched.scheduler instance
sc.enter(60, 1, self.doChecks, (sc, False))

Komut kodu kullanarak bir daemonised süreç olarak çalıştığı burada .

DoChecks'in bir parçası olarak adlandırılan bir dizi sınıf yöntemi, sistem istatistiklerini almak için sistem işlevlerini çağırmak için alt işlem modülünü kullanır:

ps = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE).communicate()[0]

Bu, tüm komut dosyası aşağıdaki hatayla çökmeden önce bir süre sorunsuz çalışır:

File "/home/admin/sd-agent/checks.py", line 436, in getProcesses
File "/usr/lib/python2.4/subprocess.py", line 533, in __init__
File "/usr/lib/python2.4/subprocess.py", line 835, in _get_handles
OSError: [Errno 12] Cannot allocate memory

Komut dosyası çöktüğünde sunucuda free -m çıktısı şöyledir:

$ free -m
                  total       used       free     shared     buffers    cached
Mem:                894        345        549          0          0          0
-/+ buffers/cache:  345        549
Swap:                 0          0          0

Sunucu CentOS 5.3 çalıştırıyor. Kendi CentOS kutularımda veya aynı sorunu bildiren başka bir kullanıcıyla çoğaltamıyorum.

Orijinal soruda önerildiği gibi, bu hatayı gidermek için birkaç şey denedim:

  1. Popen çağrısından önce ve sonra free -m çıktısının günlüğe kaydedilmesi. Bellek kullanımında önemli bir değişiklik yoktur, yani komut dosyası çalışırken bellek yavaş yavaş kullanılmaz.

  2. Popen çağrısına close_fds = True ekledim ama bu fark yaratmadı - komut dosyası hala aynı hatayla çöktü. Burada ve burada önerildi .

  3. Burada önerildiği gibi hem RLIMIT_DATA hem de RLIMIT_AS'ta (-1, -1) gösterilen rlimits'leri kontrol ettim .

  4. Bir makale , takas alanı olmamasının neden olabileceğini öne sürdü, ancak takas aslında talep üzerine (web sunucusuna göre) mevcut ve bu da burada sahte bir neden olarak önerildi .

  5. Python kaynak kodu ve yorumları tarafından yedeklendiği gibi .communicate () kullanma davranışı olduğundan işlemler kapatılıyor. buradaki .

Çeklerin tamamı adresinde bulunabilir. GitHub'da 442 satırından tanımlanan getProcesses fonksiyonu ile Bu, 520 satırından başlayarak doChecks () tarafından çağrılır.

Komut dosyası, çökmeden önce aşağıdaki çıktıyla strace ile çalıştırıldı:

recv(4, "Total Accesses: 516662\nTotal kBy"..., 234, 0) = 234
gettimeofday({1250893252, 887805}, NULL) = 0
write(3, "2009-08-21 17:20:52,887 - checks"..., 91) = 91
gettimeofday({1250893252, 888362}, NULL) = 0
write(3, "2009-08-21 17:20:52,888 - checks"..., 74) = 74
gettimeofday({1250893252, 888897}, NULL) = 0
write(3, "2009-08-21 17:20:52,888 - checks"..., 67) = 67
gettimeofday({1250893252, 889184}, NULL) = 0
write(3, "2009-08-21 17:20:52,889 - checks"..., 81) = 81
close(4)                                = 0
gettimeofday({1250893252, 889591}, NULL) = 0
write(3, "2009-08-21 17:20:52,889 - checks"..., 63) = 63
pipe([4, 5])                            = 0
pipe([6, 7])                            = 0
fcntl64(7, F_GETFD)                     = 0
fcntl64(7, F_SETFD, FD_CLOEXEC)         = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7f12708) = -1 ENOMEM (Cannot allocate memory)
write(2, "Traceback (most recent call last"..., 35) = 35
open("/usr/bin/sd-agent/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/bin/sd-agent/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python24.zip/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/plat-linux2/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python2.4/lib-tk/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/lib-dynload/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/site-packages/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
write(2, "  File \"/usr/bin/sd-agent/agent."..., 52) = 52
open("/home/admin/sd-agent/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/bin/sd-agent/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python24.zip/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/plat-linux2/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python2.4/lib-tk/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/lib-dynload/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/site-packages/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
write(2, "  File \"/home/admin/sd-agent/dae"..., 60) = 60
open("/usr/bin/sd-agent/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/bin/sd-agent/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python24.zip/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/plat-linux2/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python2.4/lib-tk/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/lib-dynload/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/site-packages/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
write(2, "  File \"/usr/bin/sd-agent/agent."..., 54) = 54
open("/usr/lib/python2.4/sched.py", O_RDONLY|O_LARGEFILE) = 8
write(2, "  File \"/usr/lib/python2.4/sched"..., 55) = 55
fstat64(8, {st_mode=S_IFREG|0644, st_size=4054, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7d28000
read(8, "\"\"\"A generally useful event sche"..., 4096) = 4054
write(2, "    ", 4)                     = 4
write(2, "void = action(*argument)\n", 25) = 25
close(8)                                = 0
munmap(0xb7d28000, 4096)                = 0
open("/usr/bin/sd-agent/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/bin/sd-agent/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python24.zip/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/plat-linux2/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python2.4/lib-tk/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/lib-dynload/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/site-packages/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
write(2, "  File \"/usr/bin/sd-agent/checks"..., 60) = 60
open("/usr/bin/sd-agent/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/bin/sd-agent/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python24.zip/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/plat-linux2/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python2.4/lib-tk/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/lib-dynload/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/site-packages/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
write(2, "  File \"/usr/bin/sd-agent/checks"..., 64) = 64
open("/usr/lib/python2.4/subprocess.py", O_RDONLY|O_LARGEFILE) = 8
write(2, "  File \"/usr/lib/python2.4/subpr"..., 65) = 65
fstat64(8, {st_mode=S_IFREG|0644, st_size=39931, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7d28000
read(8, "# subprocess - Subprocesses with"..., 4096) = 4096
read(8, "lso, the newlines attribute of t"..., 4096) = 4096
read(8, "code < 0:\n        print >>sys.st"..., 4096) = 4096
read(8, "alse does not exist on 2.2.0\ntry"..., 4096) = 4096
read(8, " p2cread\n        # c2pread    <-"..., 4096) = 4096
write(2, "    ", 4)                     = 4
write(2, "errread, errwrite)\n", 19)    = 19
close(8)                                = 0
munmap(0xb7d28000, 4096)                = 0
open("/usr/lib/python2.4/subprocess.py", O_RDONLY|O_LARGEFILE) = 8
write(2, "  File \"/usr/lib/python2.4/subpr"..., 71) = 71
fstat64(8, {st_mode=S_IFREG|0644, st_size=39931, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7d28000
read(8, "# subprocess - Subprocesses with"..., 4096) = 4096
read(8, "lso, the newlines attribute of t"..., 4096) = 4096
read(8, "code < 0:\n        print >>sys.st"..., 4096) = 4096
read(8, "alse does not exist on 2.2.0\ntry"..., 4096) = 4096
read(8, " p2cread\n        # c2pread    <-"..., 4096) = 4096
read(8, "table(self, handle):\n           "..., 4096) = 4096
read(8, "rrno using _sys_errlist (or siml"..., 4096) = 4096
read(8, " p2cwrite = None, None\n         "..., 4096) = 4096
write(2, "    ", 4)                     = 4
write(2, "self.pid = os.fork()\n", 21)  = 21
close(8)                                = 0
munmap(0xb7d28000, 4096)                = 0
write(2, "OSError", 7)                  = 7
write(2, ": ", 2)                       = 2
write(2, "[Errno 12] Cannot allocate memor"..., 33) = 33
write(2, "\n", 1)                       = 1
unlink("/var/run/sd-agent.pid")         = 0
close(3)                                = 0
munmap(0xb7e0d000, 4096)                = 0
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x589978}, {0xb89a60, [], SA_RESTORER, 0x589978}, 8) = 0
brk(0xa022000)                          = 0xa022000
exit_group(1)                           = ?

1
'boruların' veya dosya tanımlayıcılarının veya bunlarla ilgili bir çekirdek kaynağının tükenmesi mi?
Blauohr

Kontrol edin /var/log/messagesveya dmesgkomut verin.
mark4o

Günlükte bununla ilgili hiçbir şey yok.
davidmytton

Buna hiç bir çözüm buldunuz mu? Çok benzer semptomlarım var. Bol miktarda yedek belleğim var, ancak takas ekledikten sonra (bazı yanıtlarınızın önerdiği gibi) sorun ortadan kalkıyor. O zamandan şimdiye kadar geçen aylarda bir şey bulup bulmadığını merak ettim. -- Teşekkürler!
dpb

Aynı problemle karşılaşıyorum ama çözüm yok - herhangi bir fikriniz var mı?

Yanıtlar:


88

Genel bir kural (yani vanilyalı çekirdekleri) gibi, fork/ cloneile başarısızlıkları ENOMEM özellikle meydana çünkü birinin Tanrı'ya dürüst dışı bellek durumu ( dup_mm, dup_task_struct, alloc_pid, mpol_dup, mm_initvb croak) ya çünkü security_vm_enough_memory_mmseni başarısız olurken uygulayan overcommit politikasını .

Çatallanma girişimi sırasında çatallanamayan sürecin sanal boyutunu kontrol ederek başlayın ve ardından aşırı taahhüt politikasıyla ilgili olduğu için boş bellek miktarı (fiziksel ve takas) ile karşılaştırın (sayıları girin.)

Sizin özel durumda, not Virtuozzo sahip olduğu ek kontroller de overcommit icra . Üstelik ben gerçekten dan, ne kadar kontrol emin değilim içinde arkanızda, konteyner takas ve overcommit yapılandırma (icra sonucunu etkilemek amacıyla.)

Şimdi, gerçekten ilerlemek için iki seçeneğinizin kaldığını söyleyebilirim :

  • daha büyük bir örneğe geçin veya
  • betiğinizin bellek ayak izini daha etkili bir şekilde kontrol etmek için biraz kodlama çabası harcayın

Unutmayın ki, kodlama çabası siz değilsiniz, ancak amock çalıştırırken aynı sunucuda farklı bir örnekte yer alan başka bir adam ortaya çıkarsa, boşuna olabilir.

Hafıza-akıllı, biz zaten biliyoruz subprocess.Popenkullanımlarını fork/ clone kaputun altında sen ediyoruz diyoruz her zaman, yani Python kadar bellek gibi bir kez daha talep eden zaten yiyor sonra için ek MB, tüm yüzlerce yani veya execgibi cılız bir 10kB çalıştırılabilir . Olumsuz bir aşırı taahhüt politikası söz konusu olduğunda, yakında göreceksiniz .freepsENOMEM

forkBu üst sayfa tablolarına sahip olmayan alternatifler vb. Kopyalama problemi vforkve posix_spawn. Ama parçalarını yeniden yazma gibi hissetmiyorum eğer subprocess.Popenaçısından vfork/ posix_spawnkullanmayı düşünün suprocess.Popensenaryonun başlangıcında (Python'un bellek izi minimum olduğunda) de sadece bir kez, hiç bir shell script o zaman çalışır yumurtlamaya free/ ps/ sleepbir de ve başka ne betiğinize paralel döngü ; betiğin çıktısını yoklayın veya eşzamanlı olarak okuyun, eşzamansız olarak ilgilenmeniz gereken başka şeyler varsa, muhtemelen ayrı bir iş parçacığından okuyun - verilerinizi Python'da yapın, ancak çatallamayı alt işleme bırakın.

ANCAK , özel durumunuzda çağırmayı psve freetamamen atlayabilirsiniz ; Bu bilgilereprocfs , ister kendiniz ister mevcut kitaplıklar ve / veya paketler aracılığıyla erişmeyi tercih edin, doğrudan Python'da kolayca erişebilirsiniz . Eğer psve freeçalışmakta olan sadece kamu hizmetleri vardı, o zaman yapabilirsiniz ortadan subprocess.Popentamamen .

Son olarak subprocess.Popen, ilgilendiğiniz kadarıyla ne yaparsanız yapın , eğer betiğiniz bellek sızdırıyorsa, yine de sonunda duvara çarpacaksınız. Ona bir göz atın ve bellek sızıntılarını kontrol edin .


8
Çöp toplayıcının bir süre çalışmadığı durumlarda gc.collect()hemen önce çalıştırmanın subprocess.Popenyardımcı olduğunu buldum .
letmaik

Yardımcı komut dosyası stratejisini işlemek için bir deamon yazdım: github.com/SeanHayes/errand-boy Bunu müşterilerimden biriyle üretimde kullanıyorum ve "Bellek ayıramıyorum " sorunlarımız ortadan kalktı.
Seán Hayes

Aşağıdaki örneğin, basit bir tanı sevinirim /proc/fd/mapsovercommitted bellek aslında sorun olup olmadığını belirlemek için
Dima Tisnek

18

Çıktısına baktığımda, free -maslında takas belleğiniz yok gibi görünüyor. Linux'ta takasın her zaman talep üzerine otomatik olarak kullanılabilir olup olmayacağından emin değilim, ancak aynı sorunu yaşıyordum ve buradaki cevapların hiçbiri bana gerçekten yardımcı olmadı. Bununla birlikte, bir miktar takas belleği eklemek, benim durumumdaki sorunu çözdü, bu nedenle bu, aynı sorunla karşılaşan diğer insanlara yardımcı olabileceğinden, cevabımı 1GB'lık bir takasın nasıl ekleneceğine dair gönderiyorum (Ubuntu 12.04'te ancak diğer dağıtımlar için benzer şekilde çalışması gerekir.)

Önce herhangi bir takas belleğinin etkin olup olmadığını kontrol edebilirsiniz.

$sudo swapon -s

boşsa, bu, herhangi bir takas işleminin etkin olmadığı anlamına gelir. 1 GB takas eklemek için:

$sudo dd if=/dev/zero of=/swapfile bs=1024 count=1024k
$sudo mkswap /swapfile
$sudo swapon /swapfile

fstabDeğişimi kalıcı hale getirmek için aşağıdaki satırı ekleyin .

$sudo vim /etc/fstab

     /swapfile       none    swap    sw      0       0 

Kaynak ve daha fazla bilgi burada bulunabilir .


1
Bu aynı sorunu mu yoksa başka bir sorunu mu çözdü?
Dima Tisnek

Bu benim için CentOS 6.4'te yaptı. Awstats yüklenirken hatayla karşılaşıldı, teşekkürler.
Ruslan Abuzant

Bu, Kodu yürütmeme izin verse de, muhtemelen kullandığım bir kitaplıkta bulunan soruna gerçekten değinmedi.
philmaweb

1
Sorunumu çözdün. Teşekkürler! +1
sscirrus

8

takas daha önce önerilen kırmızı ringa balığı olmayabilir. Söz konusu python işleminin hemen öncesinde ne kadar büyük ENOMEM?

Çekirdek 2.6 altında, çekirdeğin /proc/sys/vm/swappinessne kadar agresif bir şekilde değiş tokuşa döneceğini kontrol eder overcommit*ve çekirdeğin hafızayı ne kadar ve ne kadar hassas bir şekilde paylaştıracağını bir göz kırpma ve baş sallama ile kaydeder. Facebook ilişki durumunuz gibi, karmaşıktır .

... ancak takas aslında talep üzerine mevcuttur (web barındırıcısına göre) ...

ancak free(1)komutunuzun çıktısına göre değil , sunucu örneğiniz tarafından tanınan takas alanı göstermez. Şimdi, web sunucunuz bu konu hakkında kesinlikle benden çok daha fazlasını biliyor olabilir, ancak kullandığım sanal RHEL / CentOS sistemleri, konuk işletim sistemi için takas yapılabildiğini bildirdi.

Red Hat KB Makalesi 15252'yi uyarlama :

Bir Red Hat Enterprise Linux 5 sistemi, anonim bellek ve sistem V paylaşılan belleğinin toplamı RAM miktarının yaklaşık 3 / 4'ünden daha az olduğu sürece, hiç takas alanı olmadan gayet iyi çalışacaktır. .... 4 GB veya daha az ram içeren sistemler en az 2 GB takas alanı [olması önerilir] .

Senin karşılaştırın /proc/sys/vmdüz CentOS 5.3 yüklemesine ayarları. Bir takas dosyası ekleyin. Cırcırlı ol swappinessve daha fazla yaşayıp yaşamadığına bak.


Python işleminin boyutunu kontrol etmenin en iyi yolu nedir? ps?
davidmytton

ps -o user,pid,vsz="Mem(Kb)" -o cmd $PYTHON_PIDveya top (1) gibi bir şey yapmalıdır.
pilcrow

7

Kolay bir düzeltme için şunları yapabilirsiniz:

echo 1 > /proc/sys/vm/overcommit_memory

Sisteminizin yeterli belleğe sahip olduğundan eminseniz. İşlemeye göre Linux'a bakın .


1
Çok teşekkür ederim! Bu kadar kolay bir çözüm, günümü kurtardınız)
igolkotek

5

Müşterinizin / kullanıcınızın, clone()sistem çağrısına müdahale eden (belki bazı belirsiz güvenlik geliştirmeleri, LIDS gibi ancak daha anlaşılmaz bir şey?) Yüklü bir çekirdek modülüne veya sürücüye sahip olduğundan veya bir şekilde bazı çekirdek veri yapılarını doldurduğundan şüphelenmeye devam ediyorum . çalışması için fork()/ clone()için gereklidir (işlem tablosu, sayfa tabloları, dosya tanımlayıcı tabloları, vb.).

İşte fork(2)man sayfasının ilgili kısmı :

HATALAR
       EAGAIN fork (), üst öğenin sayfa tablolarını kopyalamak için yeterli bellek ayıramaz ve için bir görev yapısı tahsis edemez.
              çocuk.

       EAGAIN Arayanın RLIMIT_NPROC kaynak sınırıyla karşılaşıldığından yeni bir işlem yaratmak mümkün olmadı. için
              bu sınırı aştığında, işlemin CAP_SYS_ADMIN veya CAP_SYS_RESOURCE yeteneğine sahip olması gerekir.

       ENOMEM fork (), bellek sıkı olduğundan gerekli çekirdek yapılarını ayıramadı.

Kullanıcının bunu bir stoğa, genel çekirdeğe önyükleme yaptıktan sonra ve yalnızca minimum bir modül ve sürücü kümesi yükledikten sonra denemesini öneririm (uygulamanızı / betiğinizi çalıştırmak için minimum gereklidir). Oradan, bu yapılandırmada çalıştığını varsayarsak, bununla sorunu sergileyen yapılandırma arasında ikili bir arama gerçekleştirebilirler. Bu, standart sistem yöneticisi sorun giderme 101'dir.

Sizinle ilgili satır straceşudur:

clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7f12708) = -1 ENOMEM (Cannot allocate memory)

... Başkalarının takas ve bellek kullanılabilirliğinden bahsettiğini biliyorum (ve ironik bir şekilde, en azından küçük bir takas bölümü kurmanızı tavsiye ederim, bu bir RAM diskte olsa bile ... Linux çekirdeği olduğunda kod yolları Mevcut olan küçük bir takas parçası bile, sıfır takasın mevcut olduğu yollardan (istisna işleme yolları) çok daha kapsamlı bir şekilde uygulanmıştır.

Ancak bunun hala kırmızı bir ringa balığı olduğundan şüpheleniyorum.

freeÖnbellek ve tamponlar tarafından kullanılan 0 (SIFIR) hafızanın rapor edilmesi gerçeği çok rahatsız edicidir. freeÇıktının ... ve muhtemelen buradaki uygulama sorununun, bellek tahsisine bir şekilde müdahale eden bazı tescilli çekirdek modüllerinden kaynaklandığından şüpheleniyorum .

Fork () / clone () için man sayfalarına göre, fork () sistem çağrısı, çağrınız bir kaynak sınırı ihlaline (RLIMIT_NPROC) neden olacaksa EAGAIN döndürmelidir ... ancak, EAGAIN'in döndürülüp döndürülmeyeceğini söylemez diğer RLIMIT * ihlalleri ile. Her durumda, hedefinizin / ana makinenizin bir çeşit tuhaf Vormetric veya başka güvenlik ayarları varsa (veya işleminiz bazı garip SELinux ilkeleri altında çalışıyor olsa bile), bu -ENOMEM hatasına neden olabilir.

Normal bir sıradan Linux / UNIX sorunu olması pek olası değildir. Orada standart olmayan bir şeyler oluyor.


1
Sunucu, sanallaştırma için Virtuozzo kullanan bir Medya Şablonu (dv) tabanında çalışıyor.
davidmytton

Virtuozzo mesaj panolarını ve hata izleme sistemini aramayı deneyin ve belki de Virtuozzo alt sisteminin kendisinin yükseltmelerini arayın.
Jim Dennis

2

Kullanmayı denediniz mi:

(status,output) = commands.getstatusoutput("ps aux")

Bunun benim için aynı sorunu çözdüğünü düşündüm. Ama sonra benim sürecim ortaya çıkmamak yerine öldürüldü, ki bu daha da kötüsü ..

Bazı testlerden sonra bunun yalnızca eski python sürümlerinde gerçekleştiğini buldum: 2.6.5 ile oluyor ama 2.7.2 ile değil.

Aramam beni buraya python-close_fds-issue yönlendirdi , ancak unsetting closed_fds sorunu çözmedi. Hala okumaya değer.

Python'un sadece ona göz atarak dosya tanımlayıcıları sızdırdığını buldum:

watch "ls /proc/$PYTHONPID/fd | wc -l"

Sizin gibi, komutun çıktısını yakalamak istiyorum ve OOM hatalarından kaçınmak istiyorum ... ama bu, insanların Python'un daha az hatalı bir sürümünü kullanmasının tek yolu gibi görünüyor. Uygun değil...


0

munmap (0xb7d28000, 4096) = 0
yazma (2, "OSError", 7) = 7

Şuna benzeyen baştan savma bir kod gördüm:

serrno = errno;
some_Syscall(...)
if (serrno != errno)
/* sound alarm: CATROSTOPHIC ERROR !!! */

Bunun python kodunda olup olmadığını kontrol etmelisiniz. Errno yalnızca devam eden sistem çağrısı başarısız olursa geçerlidir.

Eklemek için düzenlendi:

Bu sürecin ne kadar sürdüğünü söylemiyorsunuz. Muhtemel hafıza tüketicileri

  • çatallı süreçler
  • kullanılmayan veri yapıları
  • paylaşılan kitaplıklar
  • bellek eşlemeli dosyalar

2
Evet, ancak OP'nin aşamasından, ilk sistem çağrısı başarısızlığının - clone () 'dan - bildirildiği gibi ENOMEM olduğunu görüyoruz. Bu hata, C-kütüphanesi errnoyol boyunca birçok kez sıfırlansa da, python'un geri izleme yapısı yoluyla düşük hafızalı tökezlemesi boyunca korunur .
pilcrow

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.