bellek kullanımının değişmemesi nedeniyle sistemin donma / yanıt vermemesini önleme


48

Bir işlem çok fazla bellek gerektiriyorsa, sistem diğer tüm işlemleri takas dosyasına taşır. Görünüşe göre, X11 sunucusu veya terminal gibi gerekli işlemler.

Bir süreç sınırsız olarak tahsis edilmeye devam ederse, OOM katili tarafından öldürülene kadar her şey tepkisizleşiyor. Dizüstü bilgisayarım özellikle mantıklı görünüyor ve son derece kötü tepki veriyor. Fare imlecinin bile hareket ettirilemediği işlem sonlandırmasını bekleyerek bir ENTIRE HOUR harcadım.

Bu nasıl önlenebilir?

1) Değişimi devre dışı bırakın => Sık sık etkisiz hale gelen birçok işlemi başlatırım. Aktif olmayanlar, takas yerine taşınmalıdır.

2) Bir SSD alın => çok pahalı

3) bir maksimum bellek ulimit => ayarlayın ancak daha sonra bir programın büyük miktarda belleğe ihtiyaç duyduğu durumlarda başarısız olur. Sorun çok fazla kullanması değil, diğer süreçleri bastırmasıdır.

4) önemli programları (X11, bash, kill, top, ...) hafızada tut ve bunları asla değiştirmeyin => bu yapılabilir mi? Nasıl? belki de sadece büyük programları takas etmek?

5)?


Ve ti tekrar oldu :( Firefox çalışırken gcc başladı, her şey yarım saat boyunca engellendi Fare hareketi yok, e-kitap okuma yok
BeniBela

Ne istediğini anladığımdan emin değilim. Sistemin sahip olduğu kaynaklarla sihirleri daha hızlı yapmasını ister misiniz? Çok fazla bellek kullanan işlemleri daha erken öldürmesini istiyor musunuz?
David Schwartz

Gerçekten ihtiyacın olan şey daha fazla RAM gibi. Veya daha az "etkin olmayan" arka plan görevleri.
Daniel B,

2
OOM katilini çalışmaya zorlamak için Alt + SysRq + F tuş birleşimini kullanabilirsiniz. Bu, sisteminizin bir konsol açmasını beklemek için gereken süreyi azaltabilir, böylece bir süreci öldürebilirsiniz.
Hololeap,

Hatalıysam beni düzeltin, ancak bu sorun aslında sistem var olması gereken ama var olmayan (takas bölümü çok küçük) disk takas alanını arıyor gibi görünüyor. Yeterli takas alanı, sistemin sabit disk alanını (veya ssd'yi boşa harcayarak) boşalmasına neden olur.
saat

Yanıtlar:


45

TL; DR

Kısa geçici / cevap

  • En kolay : Daha küçük bir takas bölmesine sahip olun ve yavaş depolama alanından işlemleri çalıştırarak çekirdeğin yaşamaya çalışmasına izin vermeyin.
    • Büyük bir takas durumunda, OOM (bellek yöneticisi dışında) yakında işlem yapmaz. Tipik olarak, sanal belleğe göre hesap verir ve geçmiş deneyimlerime göre, tüm takas doluncaya kadar bir şey öldürmedi, bu yüzden çökme ve tarama sistemi ...
  • Hazırda bekletme için büyük bir takas ihtiyacınız var?
    • Denendi / sorunlu : Bazı ulimitleri ayarlayın (örn . Seçeneğini işaretleyerek kontrol edin ulimit -vve sert veya yumuşak bir sınır belirleyin ). Bu, yeterince iyi çalışıyordu, ancak WebKit’in tanıtımı sayesinde , birçok gnome uygulaması şimdi sınırsız adres alanı bekliyor ve çalışmaz!aslimits.confgigacage
    • Denenen / sorunlu : overcommit politika ve oran yönetmek denemek ve örneğin (bu azaltmak için başka bir yoludur sysctl vm.overcommit_memory, sysctl vm.overcommit_ratioancak bu yaklaşım benim için işe yaramadı.
    • Zor / karmaşık : En önemli süreçlere (ör. Ssh) bir grup önceliği uygulamayı deneyin, ancak bu şu anda v1 grubu için zahmetli görünüyor (umarım v2 bunu kolaylaştıracaktır) ...

Ben de buldum:

  • daha küçük takas alanları için yukarıdaki tavsiyeyi onaylayan bir başka yığın değişimi girişi .
  • Şu anki durum için etrafta dolaşma koruması gibi bir şey deneyebilirsin .

Daha uzun vadeli çözüm

Bekleyiniz ve bazı yukarı akış yamalarının istikrarlı distro çekirdeğe girmesini ümit ediniz. Ayrıca dağıtım şirketlerinin, masaüstü sürümlerinde GUI yanıtını öncelik sırasına koymak için çekirdek varsayılanlarını daha iyi ayarlayabileceklerini ve sistem ve grup gruplarından daha iyi yararlanabileceklerini umuyoruz.

Bazı ilgi alanları:

Bu yüzden sadece hatalı kullanıcı alan kodu ve hatalı olan distro config / defaults değil, çekirdek bunu daha iyi halledebilir.

Zaten dikkate alınan seçeneklerle ilgili yorumlar

1) Değişimi devre dışı bırakın

En azından küçük bir takas bölmesi sağlanması önerilir ( Modern sistemlerde takas için gerçekten ihtiyacımız var mı? ). Değişimi devre dışı bırakmak yalnızca kullanılmayan sayfaları değiştirmeyi engellemekle kalmaz, aynı zamanda çekirdeğin varsayılan sezgisel aşırı alım stratejisini bellek ayırma stratejisini de etkileyebilir ( Overcommit_memory = 0'daki sezgisel tarama nedir? ), Çünkü takas sayfalarında sezgisel. Takas olmadan, fazla alım yine de sezgisel (0) veya her zaman (1) modlarında çalışabilir, ancak takas yapmama ve asla (2) fazla alım stratejisinin birleşimi muhtemelen korkunç bir fikirdir. Bu nedenle çoğu durumda, takas işlemi performansa zarar vermez.

Örneğin, başlangıçta bir kereye mahsus iş için belleğe dokunan uzun süren bir işlemi düşünün, ancak daha sonra bu belleği serbest bırakmaz ve arka planda çalışmaya devam eder. İşlem bitinceye kadar çekirdeğin RAM kullanması gerekecek. Herhangi bir takas olmadan, çekirdek aktif olarak RAM kullanmak isteyen başka bir şey için sayfa çıkaramaz. Ayrıca kaç dev aygıtın tembel olduğunu ve kullanımdan sonra belleği açıkça boşaltmadığını düşünün.

3) maksimum hafıza ayarını ayarlamak

Yalnızca işlem başına uygulanır ve bir işlemin bir sistemin fiziksel olarak sahip olduğu daha fazla bellek talep etmemesi gerektiği makul bir varsayımdır! Bu nedenle, hala çılgın bir sürecin hala cömertçe yerleştirilmiş iken, çökmeyi tetiklemesini durdurmak muhtemelen yararlıdır.

4) önemli programları (X11, bash, kill, top, ...) hafızada tut ve hiçbir zaman bunları değiştir

Güzel fikir, ama o zaman bu programlar aktif olarak kullanmadıkları hafızayı değiştirecek. Program yalnızca mütevazı bir miktarda bellek isterse kabul edilebilir.

systemd 232 release , bunu mümkün kılan bazı seçenekler ekledi: Sanırım herhangi birinin hafızasının değiştirilmesini ssh gibi birimin (servisin) önlenmesi için 'MemorySwapMax = 0' kullanılabilir.

Bununla birlikte, hafıza erişimine öncelik verebilmek daha iyi olurdu.

Uzun açıklama

Linux çekirdeği sunucu iş yükleri için daha fazla ayarlanmıştır, bu yüzden GUI'nin yanıt vermesi ne yazık ki ikincil bir endişe kaynağı olmuştur ... Ubuntu 16.04 LTS'nin Masaüstü sürümündeki çekirdek bellek yönetimi ayarları diğer sunucu sürümlerinden farklı değildi. Genellikle sunucu olarak kullanılan RHEL / CentOS 7.2'deki varsayılanlarla bile eşleşir.

OOM, ulimit ve duyarlılık için dürüstlük ticareti

Thrashing'i değiştirme (çalışma hafızası, yani belirli bir zaman diliminde okunan ve yazılan sayfalar fiziksel RAM'i aştığında) depolama G / Ç'sini her zaman kilitleyecektir - hiçbir çekirdek sihirbazı bir işlemi öldürmeden sistemi kurtaramaz ya da iki...

Umarim Linux OOM tweaks'in daha yeni bir çekirdege gelmesi, bu çalisma setinin fiziksel bellek durumunu aştıgini ve bir süreci öldürdüğünü kabul ediyor. Olmadığında, çökme problemi olur. Sorun şu ki, büyük bir takas bölümüyle, çekirdek neşeyle taşınırken ve hala bellek taleplerini yerine getirirken sistem hala tavan boşluğu varmış gibi görünebilir, ancak çalışma seti, depolama alanını etkin bir şekilde işlemeye çalışıyormuş gibi değiştirmeye çalışıyor RAM.

Sunucularda kararlı, yavaş, veri kaybetmemek, takas yapmaktan düşme performans cezasını kabul eder. Masaüstlerinde işlemlerin farklı olması ve kullanıcılar işlerin duyarlı olmasını sağlamak için biraz veri kaybı (işlem fedakarlığı) yapmayı tercih eder.

Bu OOM hakkında güzel bir komik analoji idi: oom_pardon, aka xlock'umu öldürme

Bu arada, OOMScoreAdjustağırlığa yardımcı olmak ve daha önemli olarak görülen OOM öldürme işlemlerinden kaçınmak için başka bir sistem seçeneğidir.

tamponlanmış geri dönüş

Bence " Arka plan geri dönüşünü geri çekmeyin", RAM'i takan bir işlemin başka bir takas işlemine neden olduğu (diske yazma) ve toplu olarak diske yazma işleminin IO isteyen başka herhangi bir şeyi durdurabilmesini engeller. Bu, sorunun nedeninin kendisi değil, ancak yanıt verme konusundaki genel bozulmaya katkıda bulunuyor.

ulimits sınırlaması

Ulimits ile ilgili bir problem, bir sınırlamanın muhasebenin sanal bellek adres alanına (hem fiziksel hem de takas alanının birleştirilmesi anlamına geldiği) uygulanmasıdır. Başına man limits.conf:

       rss
          maximum resident set size (KB) (Ignored in Linux 2.4.30 and
          higher)

Bu yüzden sadece fiziksel RAM kullanımına uygulanacak ulimit ayarlamak artık kullanışlı görünmüyor. bundan dolayı

      as
          address space limit (KB)

sadece saygı duyulan tek kişi olarak gözüküyor.

Maalesef, WebKit / Gnome örneğinde daha ayrıntılı olarak belirtildiği gibi, sanal adres alanı tahsisi sınırlı olduğunda bazı uygulamalar çalışamaz.

Gruplar gelecekte yardımcı olmalı mı?

Şu anda, hantal görünüyor, ancak bazı çekirdek grup bayrakları cgroup_enable=memory swapaccount=1(örneğin grub config) etkinleştirmek ve ardından bellek kullanımını sınırlamak için grup bellek denetleyicisini kullanmayı deneyin.

cgroups daha gelişmiş hafıza limit özelliklerine ve 'ulimit' seçeneklerine sahiptir. CGroup v2, ulimitlerin çalışma şeklini geliştirmek için yapılan girişimlerde ipucu olduğunu belirtti.

Birleştirilmiş bellek + takas muhasebesi ve sınırlandırması, takas alanı üzerindeki gerçek kontrol ile değiştirilir.

CGroup seçenekleri sistem kaynaklı kaynak kontrol seçenekleri ile ayarlanabilir . Örneğin:

  • MemoryHigh
  • MemoryMax

Diğer faydalı seçenekler olabilir

  • IOWeight
  • CPUShares

Bunların bazı dezavantajları var:

  1. Asma. Mevcut liman işçisi dokümantasyonu kısaca% 1 ekstra bellek kullanımı ve% 10 performans düşüşünden (muhtemelen bellek ayırma işlemleriyle ilgili olarak - gerçekten belirtilmemiştir) bahseder.
  2. Cgroup / systemd olayı son zamanlarda yoğun bir şekilde yeniden çalışıldı, bu yüzden akı yukarı akış, Linux dağıtımcılarının ilk önce yerleşmesini bekleyebileceğini ima ediyor.

In CGroup v2 , onlar düşündürmektedir memory.highgaz için iyi bir seçenek olmalı ve bir süreç grubu tarafından bellek kullanımını yönetmek. Ancak bu alıntı bellek basıncı durumlarının izlenmesinin daha fazla çalışmaya ihtiyaç duyduğunu göstermektedir (2015 itibariyle).

Bir iş yükünün daha fazla belleğe ihtiyaç duyup duymadığını belirlemek için bir bellek baskısı ölçüsü - iş yükünün bellek yetersizliğinden ne kadar etkilendiği - gereklidir; ne yazık ki, bellek basıncı izleme mekanizması henüz uygulanmamıştır.

Sistem ve grup kullanıcı alanı araçları karmaşık olduğu için, uygun bir şey belirlemek ve bundan daha fazla faydalanmak için basit bir yol bulamadım. Ubuntu için cgroup ve systemd belgeleri mükemmel değil. Gelecekteki çalışma, grup ve sistemdekileri güçlendirmek için masaüstü sürümleriyle dağıtım için olmalı, böylece yüksek bellek baskısı altında, ssh ve X-Server / pencere yöneticisi bileşenleri işlemlerle rekabet etmekten kaçınmak için CPU, fiziksel RAM ve depolama IO'ya daha yüksek öncelikli erişim sağlar değiş tokuş etmekle meşgul. Çekirdeğin CPU ve G / Ç öncelikli özellikleri bir süredir var. Eksik olan fiziksel RAM'e öncelikli erişim gibi görünüyor.

Ancak, CPU ve IO öncelikleri bile uygun bir şekilde belirlenmemiş !? Sistemin cgroup limitlerini kontrol ettiğimde, cpu hisseleri vb. Uygulayabildiğim kadarıyla uygulamıştım, Ubuntu önceden tanımlanmış herhangi bir önceleme yapmamıştı. Örneğin koştum:

systemctl show dev-mapper-Ubuntu\x2dswap.swap

Bunu ssh, samba, gdm ve nginx için aynı çıktıyla karşılaştırdım. GUI ve uzaktan yönetim konsolu gibi önemli şeyler, thrashing olduğunda diğer tüm işlemlerle eşit şekilde savaşmak zorundadır.

Örnek bellek limitleri 16GB RAM sistemde

Hazırda bekletme modunu etkinleştirmek istedim, bu yüzden büyük bir takas bölümüne ihtiyacım vardı. Dolayısıyla, ulimitler, vb. İle hafifletmeye çalışılıyor.

ulimit

Ben koymak * hard as 16777216içinde /etc/security/limits.d/mem.conftek süreç fiziksel olarak mümkün olandan daha fazla bellek istemek için izin verileceği belirtildi böyle. Hepsini bir araya getirmeyi engellemeyeceğim, ancak açgözlü bellek kullanımı ya da bellek sızıntısı olan tek bir işlem olmadan çökmeye neden olabilir. Örneğin gnome-contacts, global adres listesini bir değişim sunucusundan güncelleme gibi sıradan şeyler yaparken 8GB bellek + emildiğini gördüm ...

RAM'leri çiğneyen Gnome kişileri

Görüldüğü gibi ulimit -S -v, birçok dağıtım, bu sınırsız ve “sınırsız” olarak ayarlanmış sınırına sahiptir, teoride, bir işlem çok fazla bellek gerektirebilir, ancak yalnızca aktif olarak bir altkümeyi kullanarak sona erebilir ve mutlu bir şekilde 24GB RAM olduğu söylenir. sistem sadece 16GB'a sahip. Yukarıdaki zor sınır, çekirdek açgözlü spekülatif hafıza taleplerini reddettiği zaman iptal etmek için iyi sonuç verebilecek olan işlemlere neden olacaktır.

Ancak, gnome bağlantıları gibi çılgınca şeyler de yakalar ve masaüstü yanıt vermemi kaybetmek yerine "yeterli boş hafıza yok" hatası alıyorum:

görüntü tanımını buraya girin

Adres alanı için ulimit ayarını yapan komplikasyonlar (sanal bellek)

Ne yazık ki, bazı geliştiriciler sanal belleği taklit etmeyi sevmek sonsuz bir kaynaktır ve sanal bellekte bir ulimit ayarlamak bazı uygulamaları bozabilir. Örneğin, WebKit (bazı gnome uygulamalarına bağlı), gigacageçılgınca miktarlarda sanal bellek tahsis etmeye çalışan bir güvenlik özelliği ve FATAL: Could not allocate gigacage memoryarsız bir ipucu Make sure you have not set a virtual memory limitmeydana gelen hataları ekledi . EtraftaGIGACAGE_ENABLED=noGüvenlik avantajlarından yararlanır, ancak aynı şekilde, sanal bellek tahsisini sınırlandırmamaya izin verilmemesi de, bir güvenlik özelliğinden (örneğin, hizmet reddine engel olabilecek kaynak kontrolü) izin verilmez. İronik olarak, gigacage ve gnome devs arasında, bellek tahsisinin sınırlandırılmasının kendisinin bir güvenlik kontrolü olduğunu unutmuş görünüyorlar. Ve ne yazık ki, gigome'a ​​dayanan gnome uygulamalarının açıkça daha yüksek bir limit talep etme zahmetine girmediğini fark ettim, bu nedenle yumuşak bir limit bile bu durumda durumları kırar.

Dürüst olmak gerekirse, çekirdek sanal bellek yerine yerleşik bellek kullanımına dayanarak bellek ayırmayı reddetmek için daha iyi bir iş çıkarsa, sanal bellek sınırsızdır gibi davranmak daha az tehlikeli olur.

overcommit

Uygulamaların belleğe erişimi reddedilmesini tercih ederseniz ve fazla işlemeyi durdurmak istiyorsanız, sisteminizin yüksek bellek baskısı altındayken nasıl davrandığını test etmek için aşağıdaki komutları kullanın.

Benim durumumda, varsayılan taahhüt oranı:

$ sysctl vm.overcommit_ratio
vm.overcommit_ratio = 50

Ancak, oranı aşmayı engellemek ve oranı uygulamak için politikayı değiştirirken yalnızca tam olarak yürürlüğe girer.

sudo sysctl -w vm.overcommit_memory=2

Oran, yalnızca 24 GB'lık bir bellek toplamına tahsis edilebilir (16GB RAM * 0.5 + 16GB SWAP). Bu yüzden muhtemelen OOM'un asla ortaya çıkmadığını görecektim ve süreçlerin takas halinde sürekli belleğe erişme ihtimalinin daha düşük olması muhtemel. Ancak genel sistem verimliliğini de feda edeceğim.

Bu, pek çok uygulamanın çökmesine neden olur, çünkü devs'nin bir bellek ayırma isteğini reddederek işletim sistemini zarifçe işlememesi yaygındır. Çeşitli uygulamaların kilitlenmesi riskini daha da düşürmek için, sıkışmadan (sık sık sıfırlama işleminden sonra tüm çalışmanızı kaybettiğinizden) ortaya çıkan kilitlenme riskini ortadan kaldırır. Testlerimde pek bir faydası olmadı çünkü sistem bellek baskısı altındayken masaüstünün kendisi çöktü ve bellek ayıramadı. Ancak, en azından konsolları ve SSH hala çalıştı.

VM aşırı bellek kullanımı nasıl çalışır ?

sudo sysctl -w vm.overcommit_memory=0Masaüstü grafik yığınının tamamı ve içindeki uygulamaların çökmesine rağmen, bunun için varsayılana geri dönmeyi seçtim .


3
Bu, konuyla ilgili gördüğüm en iyi yazışma ve "sadece daha fazla RAM al!" Bahsetmediğiniz bir şey çekirdek yapılandırma seçeneklerinin buna nasıl oynadığıdır. Örneğin, kullanılan preemtion modeli veya kullanılan G / Ç zamanlayıcısı bunların herhangi biri üzerinde büyük bir etkiye sahip midir?
Hololeap,

2
but the kernel won't be able to use an overcommit strategy for allocating memory and this will likely hurt performance. Even a smaller swap partition allows this. Bunun bir kanıtı var mı? Takas yapılandırılmadan çekirdeğin çok iyi
işlemeye başladığına

@ygrek, teşekkürler, ifadeler oldukça yanlış görünüyor - aşırı alım, hiçbir zaman aşırı kullanma modu (2) seçilmediği sürece, swap olmadan da çalışıyor. Varsayılan sezgisel aşırı alım modu (0) veya her zaman taahhüt (1) modu muhtemelen hala değişmeden çalışır. Takas değiştirmenin devre dışı bırakma kodunun belleği ayırma yeteneğini (ve hangi modu özel olarak etkilediğini) incittiğini okuduğumu hatırlayamıyorum. Şanssız tekrar Googled, ancak bu yarı yararlı bir yazıydı: stackoverflow.com/questions/38688824/… Cevabı uygun şekilde düzenleyeceğim.
JPvRiel

Arka plandaki geri dönüş yamasının bana yardımcı olacağını umuyordum, ancak çok yeni bir çekirdeğimdeyim (4.14.81) ve ağır disk-I / O (takas sebebi olsun ya da olmasın) altında kayda değer yanıt sorunları ile karşı karşıya kaldım. Acaba aygıt yöneticisi ya da LUKS şifrelemesi bir şekilde performans sorunlarına neden oluyor mu? Bu tür bir sorunun nasıl hata ayıklanacağına dair gerçekten çok az ipucum var.
Darius Jahandarie
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.