เมื่อระบบลีนุกซ์ของฉันเข้าใกล้เพจจิ้ง (เช่นในกรณีของฉัน, 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:ฉันยื่นข้อผิดพลาดกับเคอร์เนลตัวติดตาม ดูเหมือนว่าจะได้รับความสนใจดังนั้น ... นิ้วข้าม ...
vmstat 1>somefile
จากระบบโดยตรงแล้วดูว่ามันรายงานอะไรหลังจากระบบกลับมามีชีวิตอีกครั้ง ฉันจะลองดู
swappiness
เป็นค่าเริ่มต้น 60 (ไม่ใช่ว่าการเปลี่ยนแปลงจะให้ผลลัพธ์ที่ดีกว่า) เคอร์เนลที่ใช้กับการvmstat
รันคือ 4.14.35 แต่ฉันได้ลอง 4.15, 4.16 และฉันกลับไปที่ซีรีส์ 4.0 (!): พฤติกรรมเดิมเสมอ และไม่ใช่ว่าฉันใช้การกระจายแบบแปลก ๆ มันเป็นเพียงเดเบียน ฉันไม่ได้ใช้เคอร์เนลอิมเมจจากเดเบียน (ไม่ใช่ของฉันมีการตั้งค่าที่ผิดปกติ) แต่ฉันได้ลองหนึ่งในนั้น ... พฤติกรรมแบบเดียวกัน