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 -v
ve 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!as
limits.conf
gigacage
- 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_ratio
ancak 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, OOMScoreAdjust
ağı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:
Diğer faydalı seçenekler olabilir
Bunların bazı dezavantajları var:
- 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.
- 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.high
gaz 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 16777216
içinde /etc/security/limits.d/mem.conf
tek 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 ...
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:
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 memory
arsız bir ipucu Make sure you have not set a virtual memory limit
meydana gelen hataları ekledi . EtraftaGIGACAGE_ENABLED=no
Gü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=0
Masaü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 .