Apakah ini cara kerja paging Linux?

26

Ketika sistem Linux saya mendekati paging (yaitu, dalam kasus saya, ram 16GB hampir penuh, swap 16GB benar-benar kosong) jika proses X baru mencoba mengalokasikan sebagian memori, sistem akan sepenuhnya terkunci. Yaitu, sampai jumlah halaman yang tidak proporsional, (wrt ukuran total dan tingkat permintaan alokasi memori X) telah ditukar. Perhatikan bahwa tidak hanya gui yang menjadi sepenuhnya tidak responsif tetapi bahkan layanan dasar seperti sshd sepenuhnya diblokir.

Ini adalah dua bagian kode (memang kasar) yang saya gunakan untuk memicu perilaku ini dengan cara yang lebih "ilmiah". Yang pertama mendapat dua angka x, y dari baris perintah dan mulai mengalokasikan dan menginisialisasi banyak potongan y byte sampai lebih dari x total byte telah dialokasikan. Dan kemudian hanya tidur tanpa batas. Ini akan digunakan untuk membawa sistem di ambang paging.

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

Sepotong kode melakukan apa yang pertama dilakukan kecuali bahwa ia memiliki sleep(1);hak setelah printf(saya tidak akan mengulangi seluruh kode). Yang ini akan digunakan ketika sistem berada di ambang paging untuk membuatnya bertukar halaman dengan cara "lembut" yaitu dengan secara perlahan meminta alokasi potongan memori baru (sehingga sistem tentu harus dapat menukar halaman dan ikuti permintaan baru).

Jadi, dengan dua potong kode yang dikompilasi, mari kita sebut masing-masing exe fasteater dan sloweater, mari kita lakukan ini:

1) mulai gui favorit Anda (tentu saja tidak terlalu diperlukan)

2) mulai beberapa mem / swap meter (mis watch -n 1 free)

3) mulai beberapa contoh di fasteater x ymana x adalah dari urutan gigabytes dan y adalah dari urutan megabytes. Lakukan sampai Anda hampir memenuhi domba jantan itu.

4) mulai satu instance dari sloweater x y, lagi di mana x adalah dari urutan gigabytes dan y adalah dari urutan megabytes.

Setelah langkah 4) apa yang harus terjadi (dan itu selalu terjadi untuk sistem saya) adalah bahwa setelah kehabisan ram, sistem akan mengunci sepenuhnya. gui terkunci sshd terkunci dll. TAPI, tidak selamanya! Setelah sloweater menyelesaikan permintaan alokasi, sistem akan hidup kembali (setelah beberapa menit penguncian, bukan detik ...) dengan situasi ini:

a) ram sudah penuh

b) swap juga tentang penuh (ingat, itu kosong di awal)

c) tidak ada intervensi pembunuh.

Dan perhatikan bahwa partisi swap ada pada SSD. Jadi, sistem ini tampaknya tidak dapat secara bertahap memindahkan halaman dari ram ke swap (mungkin dari fasteaters yang baru saja tidur) untuk memberikan ruang bagi permintaan sloweater yang lambat (dan hanya beberapa megabyte).

Sekarang, seseorang mengoreksi saya jika saya salah, tetapi ini tampaknya bukan cara sistem modern seharusnya berperilaku dalam pengaturan ini. Tampaknya berperilaku seperti sistem lama (waaaaay kembali) ketika tidak ada dukungan untuk paging dan sistem memori virtual baru saja menukar seluruh ruang memori dari beberapa proses alih-alih beberapa halaman.

Bisakah seseorang menguji ini juga? Dan mungkin seseorang yang juga memiliki sistem BSD.

UPDATE 1 Saya mengikuti saran dari Mark Plotnick di bawah ini di komentar dan saya mulai vmstat 1 >outsebelum melanjutkan dengan tes paging. Anda dapat melihat hasilnya di bawah ini (saya memotong seluruh bagian awal di mana ram diisi tanpa keterlibatan swap):

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

Seperti yang Anda lihat, segera setelah swap terlibat ada swapout besar-besaran dari 15916880 Kbytes sekaligus yang, saya kira, berlangsung selama seluruh durasi sistem membeku. Dan semua ini rupanya disebabkan oleh proses (sloweater) yang hanya meminta 10MB setiap detik.

UPDATE 2: Saya melakukan instalasi cepat FreeBSD dan mengulangi skema alokasi yang sama yang digunakan dengan Linux ... dan itu semulus yang seharusnya. FreeBSD bertukar halaman secara bertahap sementara sloweater mengalokasikan semua potongan memori 10MB. Tidak ada hambatan apa pun ... WTF terjadi di sini ?!

UPDATE 3: Saya mengajukan bug dengan bugtracker kernel. Tampaknya menjadi perhatian sehingga ... semoga saja ...

John Terragon
sumber
2
Seperti yang saya sebutkan, semuanya terkunci. Saya mencoba ssh'ing dari sistem lain hanya beberapa kali.
John Terragon
2
Jika saya mulai vmstat 1 dengan output stdout, saya pikir itu akan membeku. Tapi Anda benar, saya bisa vmstat 1>somefilelangsung mulai dari sistem dan kemudian melihat apa yang dilaporkan setelah sistem hidup kembali. Saya akan mencobanya.
John Terragon
2
Saya menggunakan vmstat. Hasil dalam pembaruan di atas.
John Terragon
3
swappinessadalah default 60 (bukan berarti mengubahnya memberikan hasil yang lebih baik). Kernel yang digunakan dengan vmstatjalankan adalah 4.14.35 tapi saya sudah mencoba 4.15, 4.16 dan saya bahkan telah kembali ke seri 4.0 (!): Perilaku selalu sama. Dan bukan karena saya menggunakan beberapa distribusi aneh, itu hanya debian. Saya tidak menggunakan gambar kernel dari debian (bukan milik saya yang memiliki konfigurasi yang tidak biasa) tapi saya sudah mencoba salah satu dari mereka ... perilaku yang sama.
John Terragon
2
Diskusi yang sangat menarik tentang bug kernel! Dan sepertinya Anda mengisolasi masalah ini untuk menukar partisi yang dienkripsi dengan LUKS. Anda mungkin ingin mengedit jawaban Anda atau mungkin memposting jawaban sendiri (dengan solusi yang diketahui sejauh ini, dan mungkin terus memperbaruinya saat diskusi LKML mendapatkan hasil yang lebih konklusif.) Sangat mengesankan melihat komunitas kernel Linux bekerja! 😁
filbranden

Jawaban:

1

Inilah yang ada untuk melindungi thrash .

Secara konstan memonitor keadaan swapping dan, ketika sesuatu secara tidak sengaja mulai menempati banyak RAM, untuk sementara membekukan proses RAM-serakah, sehingga kernel memiliki waktu untuk menukar sebagian memori tanpa membuat seluruh sistem tidak responsif.

bodqhrohro
sumber
-3

Anda hanya mengalokasikan memori - Anda tidak benar-benar memasukkan apa pun di dalamnya. Program "normal" akan mengalokasikan potongan dan kemudian mulai menggunakannya. Alokasi tidak sama dengan penggunaan memori.

Jeremy Boden
sumber
3
Selamat datang di posting di Unix StackExchange. Itu memang memasukkan data di dalamnya, data itu kebetulan nol. Lihat memset (). Kernel Linux menyediakan halaman fisik RAM segera setelah Anda menulis ke halaman virtual; itu tidak melihat nilai spesifik yang ditulis.
sourcejedi
Sebenarnya, saya mengkompilasi & menjalankan ini di desktop saya mulai dengan 2GB digunakan, 6GB gratis. Ini benar-benar bertukar pada tingkat lambat pada awalnya dan hanya ketika mencapai batas melakukan pertukaran secara agresif - yang kemudian menyebabkan berbagai tindakan GUI untuk mengambil alih.
Jeremy Boden