นี่เป็นวิธีที่เพจจิ้งของ Linux ควรทำงานหรือไม่


26

เมื่อระบบลีนุกซ์ของฉันเข้าใกล้เพจจิ้ง (เช่นในกรณีของฉัน, RAM 16GB เกือบเต็ม, 16GB swap ว่างเปล่าอย่างสมบูรณ์) หากกระบวนการใหม่ X พยายามจัดสรรหน่วยความจำบางส่วนที่ระบบล็อคอย่างสมบูรณ์ นั่นคือจนกว่าจะมีจำนวนหน้าไม่สมบูรณ์ (wrt ขนาดรวมและอัตราของการร้องขอการจัดสรรหน่วยความจำของ X) ได้ถูกสลับออก โปรดสังเกตว่าไม่เพียง แต่ gui เท่านั้นที่ไม่ตอบสนองอย่างสมบูรณ์ แต่บริการพื้นฐานอย่าง sshd จะถูกบล็อกอย่างสมบูรณ์

เหล่านี้เป็นรหัสสองชิ้น (หยาบยอมรับ) ที่ฉันใช้เพื่อเรียกพฤติกรรมนี้ในทาง "วิทยาศาสตร์" มากขึ้น คนแรกที่ได้รับสองตัวเลข x, y จากบรรทัดคำสั่งและดำเนินการเพื่อจัดสรรและเริ่มต้นชิ้นจำนวนมากของ y ไบต์จนกว่า x ไบต์ทั้งหมดได้รับการจัดสรร และจากนั้นก็นอนหลับไปเรื่อย ๆ สิ่งนี้จะถูกใช้เพื่อนำระบบเข้าสู่เพจ

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

ส่วนที่สองของโค้ดทำสิ่งที่ถูกต้องยกเว้นว่ามันมีsleep(1);สิทธิหลังจากprintf(ฉันจะไม่ทำซ้ำรหัสทั้งหมด) อันนี้จะถูกใช้เมื่อระบบอยู่ในขอบของเพจจิ้งเพื่อให้มันสลับหน้าออกในลักษณะ "อ่อนโยน" คือโดยค่อย ๆ ร้องขอการจัดสรรหน่วยความจำใหม่ (เพื่อให้ระบบควรสลับหน้าได้อย่างแน่นอน และติดตามคำขอใหม่)

ดังนั้นด้วยโค้ดสองชิ้นที่คอมไพล์กันเราจะเรียกว่าตัวเร่งความเร็วและตัวเร่งความเร็วที่เกี่ยวข้องกันดังนี้:

1) เริ่ม gui ที่คุณชื่นชอบ (ไม่จำเป็นอย่างแน่นอนแน่นอน)

2) เริ่ม mem / swap meter (เช่นwatch -n 1 free)

3) เริ่มต้นอินสแตนซ์จำนวนมากfasteater x yโดยที่ x เป็นคำสั่งของกิกะไบต์และ y เป็นลำดับเมกะไบต์ ทำจนกว่าคุณจะเกือบเติม ram

4) เริ่มต้นหนึ่งอินสแตนซ์sloweater x yอีกครั้งโดยที่ x เป็นลำดับกิกะไบต์และ y เป็นลำดับเมกะไบต์

หลังจากขั้นตอนที่ 4) สิ่งที่ควรเกิดขึ้น (และมักเกิดขึ้นกับระบบของฉัน) คือหลังจากที่ใช้ RAM หมดไประบบจะล็อคอย่างสมบูรณ์ กุยถูกล็อค sshd ถูกล็อค ฯลฯ แต่ไม่ตลอดไป! หลังจากตัวชะลอความเร็วเสร็จสิ้นการร้องขอการจัดสรรระบบจะกลับมามีชีวิตอีกครั้ง (หลังจากไม่กี่นาทีของการล็อคไม่ใช่วินาที ... ) กับสถานการณ์นี้:

a) ram เต็ม

b) การแลกเปลี่ยนยังเต็ม (จำได้ว่ามันว่างเปล่าในตอนแรก)

c) ไม่มีการแทรกแซงของนักฆ่าอุ้ม

และสังเกตว่าพาร์ติชั่น swap นั้นอยู่บน SSD ดังนั้นระบบดูเหมือนจะไม่สามารถย้ายหน้าจากหน่วยความจำไปยังหน่วยความจำแบบค่อยเป็นค่อยไป (น่าจะมาจากผู้ที่กำลังหลับเร็ว) เพื่อให้มีพื้นที่สำหรับการร้องขอที่ช้า (และเพียงไม่กี่เมกะไบต์) ของผู้ทำงานช้า

ตอนนี้บางคนแก้ไขให้ฉันถ้าฉันผิด แต่ดูเหมือนจะไม่เป็นไปตามที่ระบบสมัยใหม่ควรทำในการตั้งค่านี้ ดูเหมือนว่าจะทำงานเหมือนระบบเก่า (waaaaay ย้อนกลับ) เมื่อไม่มีการสนับสนุนสำหรับการเพจและระบบหน่วยความจำเสมือนเพิ่งสลับพื้นที่หน่วยความจำทั้งหมดของกระบวนการบางอย่างแทนที่จะเป็นสองสามหน้า

ใครบางคนสามารถทดสอบสิ่งนี้ได้เช่นกัน? และบางทีคนที่มีระบบ BSD ด้วย

อัปเดต 1 ฉันทำตามคำแนะนำจากMark Plotnickด้านล่างในความคิดเห็นและฉันเริ่มvmstat 1 >outก่อนที่จะดำเนินการทดสอบการเพจ คุณสามารถดูผลลัพธ์ด้านล่าง (ฉันตัดส่วนเริ่มต้นทั้งหมดที่มีการเติม ram โดยไม่ต้องมีส่วนร่วมของ 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

อย่างที่คุณสามารถเห็นได้ทันทีที่มีการแลกเปลี่ยนเกิดขึ้นจะมีการแลกเปลี่ยนครั้งใหญ่ที่ 15916880 Kbytes ทั้งหมดในครั้งเดียวซึ่งฉันเดาว่าจะคงอยู่ตลอดระยะเวลาการแช่แข็งของระบบ และทั้งหมดนี้เกิดจากกระบวนการ (ตัวชะลอความเร็ว) ที่เพิ่งถาม 10MB ทุกวินาที

UPDATE 2:ฉันทำการติดตั้ง FreeBSD อย่างรวดเร็วและทำซ้ำแผนการจัดสรรเดียวกันกับที่ใช้กับ Linux ... และมันก็ราบรื่นอย่างที่ควรจะเป็น FreeBSD เปลี่ยนหน้าไปเรื่อย ๆ ในขณะที่ตัวชะลอความเร็วจะจัดสรรหน่วยความจำ 10MB ทั้งหมด ไม่มีใครผูกปมชนิดใด ... WTF กำลังเกิดขึ้นที่นี่!

อัปเดต 3:ฉันยื่นข้อผิดพลาดกับเคอร์เนลตัวติดตาม ดูเหมือนว่าจะได้รับความสนใจดังนั้น ... นิ้วข้าม ...


2
อย่างที่ฉันพูดไปทุกอย่างถูกล็อค ฉันลอง ssh'ing จากระบบอื่นมันหมดเวลาแล้ว
John Terragon

2
ถ้าฉันเริ่ม vmstat 1 ด้วยเอาต์พุต stdout ฉันคิดว่ามันจะหยุด แต่คุณพูดถูกฉันจะเริ่มvmstat 1>somefileจากระบบโดยตรงแล้วดูว่ามันรายงานอะไรหลังจากระบบกลับมามีชีวิตอีกครั้ง ฉันจะลองดู
John Terragon

2
ฉันใช้ vmstat ผลลัพธ์ในการอัพเดตด้านบน
John Terragon

3
swappinessเป็นค่าเริ่มต้น 60 (ไม่ใช่ว่าการเปลี่ยนแปลงจะให้ผลลัพธ์ที่ดีกว่า) เคอร์เนลที่ใช้กับการvmstatรันคือ 4.14.35 แต่ฉันได้ลอง 4.15, 4.16 และฉันกลับไปที่ซีรีส์ 4.0 (!): พฤติกรรมเดิมเสมอ และไม่ใช่ว่าฉันใช้การกระจายแบบแปลก ๆ มันเป็นเพียงเดเบียน ฉันไม่ได้ใช้เคอร์เนลอิมเมจจากเดเบียน (ไม่ใช่ของฉันมีการตั้งค่าที่ผิดปกติ) แต่ฉันได้ลองหนึ่งในนั้น ... พฤติกรรมแบบเดียวกัน
John Terragon

2
การอภิปรายที่น่าสนใจมากในข้อผิดพลาดเคอร์เนล! และดูเหมือนว่าคุณแยกปัญหานี้เพื่อสลับพาร์ติชันที่เข้ารหัสด้วย LUKS คุณอาจต้องการแก้ไขคำตอบของคุณหรืออาจโพสต์คำตอบด้วยตัวเอง (ด้วยวิธีแก้ปัญหาที่รู้จักกันมานานและอาจปรับปรุงให้ดีขึ้นเรื่อย ๆ เนื่องจากการอภิปรายของ LKML ทำให้ได้ผลลัพธ์ที่เป็นข้อสรุปมากขึ้น) ประทับใจจริง ๆ 😁
filbranden

คำตอบ:


1

นี่คือสิ่งที่สิ่งที่ป้องกัน thrashมีอยู่สำหรับ

มันจะตรวจสอบสถานะการสลับอย่างต่อเนื่องและเมื่อมีบางสิ่งที่บังเอิญเริ่มครอบครอง RAM จำนวนมากหยุดกระบวนการ RAM- โลภชั่วคราวดังนั้นเคอร์เนลจึงมีเวลาสำหรับการแลกเปลี่ยนหน่วยความจำบางส่วนโดยไม่ทำให้ระบบทั้งระบบไม่ตอบสนอง


-3

คุณจัดสรรหน่วยความจำเท่านั้น - คุณไม่ได้ใส่อะไรลงไป โปรแกรม "ปกติ" จะจัดสรรชิ้นแล้วเริ่มใช้มัน การจัดสรรไม่เหมือนกับการใช้หน่วยความจำ


3
ยินดีต้อนรับสู่การโพสต์บน Unix StackExchange มันใส่ข้อมูลเข้าไปในนั้นข้อมูลนั้นก็จะกลายเป็นศูนย์ ดู memset () เคอร์เนล Linux จัดเตรียมหน้าฟิสิคัลของ RAM ทันทีที่คุณเขียนไปยังเพจเสมือน มันไม่ได้ดูค่าเฉพาะที่เขียน
sourcejedi

ที่จริงแล้วฉันรวบรวมและเรียกใช้บนเดสก์ท็อปของฉันเริ่มต้นที่ใช้ 2GB, 6GB ฟรี จริง ๆ แล้วมันสลับกันในอัตราที่ช้าในตอนแรกและเมื่อมันถึงขีด จำกัด แล้วมันก็จะทำการแลกเปลี่ยนอย่างจริงจัง - ซึ่งทำให้เกิดการกระทำของ GUI หลายอย่างที่จะยึด
Jeremy Boden
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.