Đây có phải là cách Linux phân trang nên hành xử?


26

Khi hệ thống Linux của tôi gần phân trang (nghĩa là trong trường hợp của tôi, ram 16 GB gần đầy, hoán đổi 16 GB hoàn toàn trống) nếu một quy trình mới X cố gắng phân bổ một số bộ nhớ mà hệ thống khóa hoàn toàn. Đó là, cho đến khi một số lượng trang không tương xứng, (ghi tổng kích thước và tỷ lệ yêu cầu phân bổ bộ nhớ của X) đã được hoán đổi. Lưu ý rằng không chỉ gui trở nên hoàn toàn không phản hồi mà ngay cả các dịch vụ cơ bản như sshd cũng bị chặn hoàn toàn.

Đây là hai đoạn mã (thừa nhận thô thiển) mà tôi sử dụng để kích hoạt hành vi này theo cách "khoa học" hơn. Số đầu tiên nhận được hai số x, y từ dòng lệnh và tiến hành phân bổ và khởi tạo nhiều khối y byte cho đến khi hơn x tổng số byte được phân bổ. Và sau đó chỉ ngủ vô thời hạn. Điều này sẽ được sử dụng để đưa hệ thống trên bờ vực phân trang.

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

Đoạn mã thứ hai thực hiện chính xác những gì mã đầu tiên thực hiện ngoại trừ việc nó có sleep(1);quyền sau printf(Tôi sẽ không lặp lại toàn bộ mã). Cái này sẽ được sử dụng khi hệ thống đang ở trạng thái phân trang để khiến nó hoán đổi các trang theo cách "nhẹ nhàng" tức là bằng cách từ từ yêu cầu phân bổ các đoạn bộ nhớ mới (để hệ thống chắc chắn có thể hoán đổi các trang và theo kịp với các yêu cầu mới).

Vì vậy, với hai đoạn mã được biên dịch, hãy gọi exeater fasteater và Sloweater tương ứng, hãy làm điều này:

1) bắt đầu gui yêu thích của bạn (tất nhiên không cần thiết lắm)

2) bắt đầu một số mem / trao đổi mét (ví dụ watch -n 1 free)

3) bắt đầu nhiều trường hợp trong fasteater x yđó x là thứ tự của gigabyte và y là thứ tự của megabyte. Làm điều đó cho đến khi bạn gần như lấp đầy ram.

4) bắt đầu một thể hiện của sloweater x y, một lần nữa trong đó x là thứ tự của gigabyte và y là thứ tự của megabyte.

Sau bước 4) điều gì sẽ xảy ra (và nó luôn xảy ra với hệ thống của tôi) là ngay sau khi hết ram, hệ thống sẽ khóa hoàn toàn. gui bị khóa sshd bị khóa vv NHƯNG, không phải là mãi mãi! Sau khi bộ xử lý chậm hoàn thành các yêu cầu phân bổ, hệ thống sẽ hoạt động trở lại (sau vài phút khóa, không phải vài giây ...) với tình huống này:

a) ram đã đầy

b) hoán đổi cũng gần đầy (hãy nhớ rằng lúc đầu nó trống rỗng)

c) không có sự can thiệp của kẻ giết người.

Và lưu ý rằng phân vùng trao đổi là trên một ổ SSD. Vì vậy, hệ thống dường như không thể chuyển dần các trang từ ram sang hoán đổi (có lẽ là từ các thiết bị nhanh đang ngủ) để tạo không gian cho các yêu cầu chậm (và chỉ vài megabyte) của bộ làm chậm.

Bây giờ, ai đó sửa tôi nếu tôi sai, nhưng điều này dường như không phải là cách một hệ thống hiện đại nên hành xử trong cài đặt này. Nó dường như hoạt động giống như các hệ thống cũ (waaaaay trở lại) khi không có hỗ trợ phân trang và hệ thống bộ nhớ ảo chỉ thay đổi toàn bộ không gian bộ nhớ của một số tiến trình thay vì vài trang.

Ai đó cũng có thể kiểm tra điều này? Và có lẽ ai đó cũng có hệ thống BSD.

CẬP NHẬT 1 Tôi đã làm theo lời khuyên từ Mark Plotnick bên dưới trong các bình luận và tôi đã bắt đầu vmstat 1 >outtrước khi tiến hành thử nghiệm phân trang. Bạn có thể thấy kết quả bên dưới (Tôi đã cắt toàn bộ phần ban đầu trong đó ram được lấp đầy mà không có sự tham gia trao đổi):

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

Như bạn có thể thấy, ngay khi hoán đổi được tham gia, có một sự hoán đổi khổng lồ là 15916880 Kbyte cùng một lúc, theo tôi đoán, kéo dài trong toàn bộ thời gian hệ thống đóng băng. Và tất cả những điều này rõ ràng là do một quá trình (trình làm chậm) chỉ yêu cầu 10MB mỗi giây.

CẬP NHẬT 2: Tôi đã cài đặt nhanh FreeBSD và lặp lại sơ đồ phân bổ tương tự được sử dụng với Linux ... và nó vẫn mượt mà như mong muốn. FreeBSD hoán đổi các trang dần dần trong khi bộ làm chậm phân bổ tất cả các bộ nhớ 10 MB của nó. Không một cú huých nào cả ... WTF đang diễn ra ở đây?!

CẬP NHẬT 3: Tôi đã gửi một lỗi với kernel bugtracker. Có vẻ như đang được chú ý nên ... ngón tay đan chéo ...


2
Như tôi đã đề cập, mọi thứ đều bị khóa. Tôi đã thử ssh'ing từ một hệ thống khác.
John Terragon

2
Nếu tôi bắt đầu vmstat 1 với đầu ra xuất chuẩn, tôi nghĩ nó sẽ bị đóng băng. Nhưng bạn đã đúng, tôi chỉ có thể bắt đầu vmstat 1>somefiletrực tiếp từ hệ thống và sau đó xem những gì nó báo cáo sau khi hệ thống hoạt động trở lại. Tôi sẽ thử xem.
John Terragon

2
Tôi đã sử dụng vmstat. Kết quả trong bản cập nhật ở trên.
John Terragon

3
swappinesslà 60 mặc định (không thay đổi nó mang lại kết quả tốt hơn). Hạt nhân được sử dụng với lần vmstatchạy là 4.14,35 nhưng tôi đã thử 4.15, 4.16 và thậm chí tôi đã quay lại loạt 4.0 (!): Luôn luôn là hành vi tương tự. Và không phải là tôi đang sử dụng một số phân phối kỳ lạ, nó chỉ là debian. Tôi không sử dụng hình ảnh hạt nhân từ debian (không phải hình ảnh của tôi có cấu hình bất thường) nhưng tôi đã thử một trong những ... hành vi tương tự.
John Terragon

2
Thảo luận rất thú vị về lỗi kernel! Và có vẻ như bạn đã tách biệt vấn đề này để trao đổi phân vùng được mã hóa bằng LUKS. Bạn có thể muốn tự chỉnh sửa câu trả lời của mình hoặc có thể tự mình đăng câu trả lời (với các cách giải quyết đã biết và có thể tiếp tục cập nhật khi thảo luận về LKML có kết quả rõ ràng hơn.) Thật ấn tượng khi thấy cộng đồng nhân Linux hoạt động! 😁
filbranden

Câu trả lời:


1

Đây chính xác là những gì thrash-bảo vệ tồn tại cho.

Nó liên tục theo dõi trạng thái tráo đổi và khi một thứ gì đó vô tình bắt đầu chiếm nhiều RAM, tạm thời đóng băng các quá trình tham lam RAM, do đó, hạt nhân có thời gian để tráo đổi một số bộ nhớ mà không làm cho toàn bộ hệ thống không phản hồi.


-3

Bạn chỉ phân bổ bộ nhớ - bạn thực sự không đặt bất cứ thứ gì vào đó. Một chương trình "bình thường" sẽ phân bổ một đoạn và sau đó bắt đầu sử dụng nó. Phân bổ không giống như sử dụng bộ nhớ.


3
Chào mừng bạn đến đăng bài trên Unix StackExchange. Nó không đặt dữ liệu vào đó, dữ liệu đó chỉ bằng không. Xem phần ghi nhớ (). Nhân Linux cung cấp một trang vật lý của RAM ngay khi bạn ghi vào trang ảo; nó không nhìn vào giá trị cụ thể được viết.
nguồn

Trên thực tế, tôi đã biên dịch và chạy nó trên máy tính để bàn của tôi bắt đầu với 2GB được sử dụng, 6GB miễn phí. Nó thực sự đã tráo đổi với tốc độ chậm ban đầu và chỉ khi đạt đến giới hạn, nó mới trao đổi mạnh mẽ - điều này sau đó khiến các hành động GUI khác nhau bị chiếm giữ.
Jeremy Boden
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.