Linux disk belleği böyle mi davranmalı?


26

Linux sistemim sayfalamaya yaklaştığında (yani benim durumumda, 16GB koç neredeyse dolu, 16GB tamamen boşalır), eğer yeni bir X işlemi sistem tamamen kilitlendiğinde bir bellek ayırmaya çalışırsa. Yani, orantısız miktarda sayfa (X'in bellek ayırma isteklerinin toplam büyüklüğü ve oranı ile) değiştirildi. Sadece GUI'nin tamamen tepkisiz hale geldiğine değil, sshd gibi temel hizmetlerin bile tamamen engellendiğine dikkat edin.

Bunlar, bu davranışı daha "bilimsel" bir şekilde tetiklemek için kullandığım iki kod parçası (kuşkusuz kaba). İlki komut satırından iki sayı x, y alır ve x toplam bayttan daha fazla tahsis edilene kadar birden fazla y bayt parçasını ayırıp başlatır. Ve sonra sadece süresiz uyur. Bu, sistemi sayfalamanın eşiğine getirmek için kullanılacak.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char** argv) {
   long int max = -1;
   int mb = 0;
   long int size = 0;
   long int total = 0;
   char* buffer;

   if(argc > 1)
     {
       max = atol(argv[1]);
       size = atol(argv[2]);
     }
   printf("Max: %lu bytes\n", max);
   while((buffer=malloc(size)) != NULL && total < max) {
       memset(buffer, 0, size);
       mb++;
       total=mb*size;
       printf("Allocated %lu bytes\n", total);       
   }      
   sleep(3000000);
   return 0;
}

İkinci kod parçası tam olarak ilkinden sonra yaptığı şeyi yapar sleep(1);. printf(Kodun tamamını tekrarlamayacağım). Bu, sistem sayfaların "nazik" bir şekilde değiştirilmesini sağlamak için sayfalamanın eşiğine geldiğinde kullanılacak, yani yeni bellek parçalarının tahsis edilmesini yavaşça talep ederek (sistemin kesinlikle sayfaları takas edebilmesi için kullanılacaktır) ve yeni isteklere yetişmek).

Böylece, iki kod parçası derlendiğinde, ilgili exes fasteater ve sloweater'ı çağıralım, şunu yapalım:

1) favori gui'nizi başlatın (elbette kesinlikle gerekli değil)

2) mem / swap metreyi başlatır (örneğin watch -n 1 free)

3) fasteater x yx'in gigabayt sırasına sahip olduğu ve y'nin megabayt sırasına sahip olduğu birden fazla örneği başlatın . Neredeyse koçu dolana kadar yap.

4) bir örneğini sloweater x ytekrar başlatın , burada x, gigabaytların sırası ve y, megabaytların sırasıdır.

4. adımdan sonra) ne olması gerektiği (ve her zaman sistemim için gerçekleşir), koçu tükettikten hemen sonra, sistemin tamamen kilitleneceğidir. GUI kilitli sshd kilitli vb. Yavaşlatıcı tahsis taleplerini tamamladıktan sonra, sistem şu durumla tekrar canlanacaktır (birkaç dakika kilitlendikten sonra, saniye değil ...):

a) Koç tam dolu

b) takas da doludur (başlangıçta boştu, unutma)

c) Katil müdahalesinin olmaması.

Ve takas bölümünün bir SSD üzerinde olduğuna dikkat edin. Bu nedenle, sistem yavaşlayıcının yavaş (ve sadece birkaç megabaytlık) isteğine yer açmak için sayfaları yavaş yavaş ramdan takas alanına (muhtemelen sadece uyuyan hızlı okuyuculardan) değiştiremiyor gibi görünüyor.

Şimdi, birisi yanlış olduğumda beni düzeltir, ancak modern bir sistemin bu ortamda davranması gerektiği gibi görünmüyor. Sayfalama desteği olmadığında ve eski bellek sistemi (waaaaay geri) gibi davranıyor ve sanal bellek sistemi birkaç sayfa yerine bazı işlemlerin tüm bellek alanını değiştirdi.

Birisi bunu da test edebilir mi? Ve belki de BSD sistemi olan biri.

GÜNCELLEME 1 Yorumlarda Mark Plotnick'in tavsiyelerini takip ettim vmstat 1 >outve çağrı testine geçmeden önce başladım . Aşağıdaki sonucu görebilirsiniz (koçun takas edilmeden doldurulduğu başlangıç ​​kısmının tamamını kestim):

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
0  0   6144 160792      8 272868    0    0     0     0  281 1839  1  0 99  0  0
0  0   6144 177844      8 246096    0    0     0     0  425 2300  1  1 99  0  0
0  0   6144 168528      8 246112    0    0    16     0  293 1939  1  0 99  0  0
0  0   6144 158320      8 246116    0    0     0     0  261 1245  0  0 100  0  0
2  0  10752 161624      8 229024    0 4820 17148  4820  845 3656  1  2 97  0  0
2  0  10752 157300      8 228096    0    0 88348     0 2114 8902  0  5 94  1  0
0  0  10752 176108      8 200052    0    0 108312     0 2466 9772  1  5 91  3  0
0  0  10752 170040      8 196780    0    0 17380     0  507 1895  0  1 99  0  0
0 10  10752 160436      8 191244    0    0 346872    20 4184 17274  1  9 64 26  0
0 29 12033856 152888      8 116696 5992 15916880 1074132 15925816 819374 2473643  0 94  0  6  0
3 21 12031552 295644      8 136536 1188    0 11348     0 1362 3913  0  1 10 89  0
0 11 12030528 394072      8 151000 2016    0 17304     0  907 2867  0  1 13 86  0
0 11 12030016 485252      8 158528  708    0  7472     0  566 1680  0  1 23 77  0
0 11 12029248 605820      8 159608  900    0  2024     0  371 1289  0  0 31 69  0
0 11 12028992 725344      8 160472 1076    0  1204     0  387 1381  0  1 33 66  0
0 12 12028480 842276      8 162056  724    0  3112     0  357 1142  0  1 38 61  0
0 13 12027968 937828      8 162652  776    0  1312     0  363 1191  0  1 31 68  0
0  9 12027456 1085672      8 163260  656    0  1520     0  439 1497  0  0 30 69  0
0 10 12027200 1207624      8 163684  728    0   992     0  411 1268  0  0 42 58  0
0  9 12026688 1331492      8 164740  600    0  1732     0  392 1203  0  0 36 64  0
0  9 12026432 1458312      8 166020  628    0  1644     0  366 1176  0  0 33 66  0

Görebildiğiniz gibi, takas işlemi gerçekleşir gerçekleşmez, bir kerede 15916880 Kbyte büyüklüğünde bir takas var, sanırım, sistemin donma süresi boyunca devam ediyor. Ve bunların hepsi görünüşte her saniye 10 MB isteyen bir işlemden (yavaşlama) kaynaklanıyor.

GÜNCELLEME 2: Hızlı bir FreeBSD kurulumu yaptım ve Linux ile kullanılan tahsisat şemasını tekrarladım ... ve olması gerektiği kadar yumuşaktı. FreeBSD yavaş yavaş sayfalarını değiştirirken yavaşlayıcı tüm 10MB'lık bellek parçalarını ayırdı. Hiçbir şekilde bir aksaklık olmaz ... WTF burada mı oluyor ?!

GÜNCELLEME 3: Çekirdek bugtracker ile bir hata dosyaladım . Biraz dikkat çekiyor gibi görünüyor ... ... parmaklar geçti ...


2
Bahsettiğim gibi, her şey kilitli. Sadece zaman aşımına uğradı başka bir sistemden ssh'ing çalıştı.
John Terragon

2
Vmstat 1'i stdout çıkışıyla başlatırsam, donacağını düşünüyorum. Ama haklısın, vmstat 1>somefiledoğrudan sistemden başlayabilirim ve daha sonra sistem hayata döndükten sonra ne rapor ettiğini görebilirim. Bunu deneyeceğim.
John

2
Vmstat kullandım. Yukarıdaki güncellemenin sonuçları.
John Terragon

3
swappinessVarsayılan 60’tır (bunu değiştirmek daha iyi sonuç vermez). vmstatKoşuda kullanılan çekirdek 4.14.35'tir ancak 4.15, 4.16 denedim ve hatta 4.0 serisine geri döndüm (!): Her zaman aynı davranış. Ve garip bir dağıtım kullandığımdan değil, sadece debian. Debian'ın çekirdek görüntülerini kullanmıyorum (benimki olağandışı yapılandırmalara sahip değil) ama bunlardan birini denedim ... aynı davranış.
John Terragon

2
Çekirdek böceği hakkında çok ilginç bir tartışma! LUKS ile şifrelenmiş bölümü değiştirmek için bu sorunu izole etmişsiniz gibi görünüyor. Cevabınızı düzenlemek veya muhtemelen kendiniz bir cevap göndermek isteyebilirsiniz (şu ana kadar bilinen çözümlerle birlikte ve belki de LKML tartışması daha kesin sonuçlara ulaştığında güncellemeye devam edin.) Linux çekirdeği topluluğunu işyerinde görmek gerçekten etkileyici! Fil
filbranden

Yanıtlar:


1

Bu tam olarak thrash-koruma için var.

Sürekli olarak takas durumunu izler ve bir şey yanlışlıkla çok fazla RAM işgal etmeye başladığında, RAM açgözlü işlemleri geçici olarak dondurur, böylece çekirdeğin tüm sistemi tepkisiz hale getirmeden bazı bellekleri değiştirmeye zamanı vardır.


-3

Sadece bellek ayırıyorsunuz - aslında içine hiçbir şey koymuyorsunuz. Bir "normal" program bir yığın tahsis eder ve kullanmaya başlar. Tahsisat bellek kullanımı ile aynı değildir.


3
Unix StackExchange'te yayınlamaya hoş geldiniz. İçine veri koyar, bu veri sadece sıfır olur. Memset'e bakınız (). Linux çekirdeği, sanal sayfaya yazdığınız anda fiziksel bir RAM sayfası sunar; Yazılan belirli bir değere bakmıyor.
kaynakjedi

Aslında, bunu 6GB ücretsiz kullanılan 2GB ile başlayarak masaüstümde derledim ve çalıştırdım. Aslında başlangıçta yavaş bir hızda değişti ve yalnızca sınıra çarptığında agresif bir şekilde yer değiştirdi - bu da çeşitli GUI eylemlerinin yakalanmasına neden oldu.
Jeremy Boden
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.