Quản lý bộ nhớ Linux khác với các hệ thống khác. Nguyên tắc chính là bộ nhớ không được sử dụng là bộ nhớ bị lãng phí. Trong nhiều cách, Linux cố gắng tối đa hóa việc sử dụng bộ nhớ, kết quả (phần lớn thời gian) trong hiệu suất tốt hơn.
Nó không phải là "không có gì hoạt động" trong Linux, nhưng hành vi của nó hơi khác một chút so với bạn mong đợi.
Khi các trang bộ nhớ được lấy từ tệp mmapped, hệ điều hành phải quyết định trang bộ nhớ vật lý nào sẽ phát hành (hoặc hoán đổi) để sử dụng. Nó sẽ tìm các trang dễ trao đổi hơn (không yêu cầu ghi đĩa ngay lập tức) và ít có khả năng được sử dụng lại.
Cuộc gọi POSIX madvice() phục vụ cho hệ thống biết ứng dụng của bạn sẽ sử dụng các trang như thế nào. Nhưng như tên gọi, đó là lời khuyên để hệ điều hành được thiết kế tốt hơn trong việc đưa ra các quyết định hoán đổi và phân trang. Nó không phải là một chính sách hay một trật tự.
Để chứng minh hiệu ứng của madvice() trên Linux, tôi đã sửa đổi một trong các bài tập mà tôi cung cấp cho sinh viên của mình. Xem complete source code here. Hệ thống của tôi là 64-bit và có 2 GB RAM, khoảng 50% hiện đang được sử dụng. Sử dụng chương trình để mmap một tập tin 2 GB, đọc nó tuần tự và loại bỏ tất cả mọi thứ. Nó báo cáo việc sử dụng RSS cứ 200 MB được đọc.Kết quả mà không madvice():
<[email protected]> ~% ./madvtest file.dat n
0 : 3 MB
200 : 202 MB
400 : 402 MB
600 : 602 MB
800 : 802 MB
1000 : 1002 MB
1200 : 1066 MB
1400 : 1068 MB
1600 : 1078 MB
1800 : 1113 MB
2000 : 1113 MB
Linux giữ đẩy mọi thứ ra khỏi bộ nhớ cho đến khoảng 1 GB được đọc. Sau đó, nó bắt đầu gây áp lực cho quá trình (vì 50% bộ nhớ khác đã được kích hoạt bởi các tiến trình khác) và ổn định cho đến cuối tập tin.
Bây giờ, với madvice():
<[email protected]> ~% ./madvtest file.dat y
0 : 3 MB
200 : 202 MB
400 : 402 MB
600 : 494 MB
800 : 501 MB
1000 : 518 MB
1200 : 530 MB
1400 : 530 MB
1600 : 530 MB
1800 : 595 MB
2000 : 788 MB
Lưu ý rằng Linux quyết định phân bổ các trang để quá trình này chỉ cho đến khi nó đạt khoảng 500 MB, sớm hơn nhiều so với không madvice(). Điều này là do sau đó, các trang hiện tại trong bộ nhớ dường như có giá trị hơn nhiều so với các trang được đánh dấu là truy cập tuần tự bởi quá trình này. Có một ngưỡng trong VMM xác định khi nào để bắt đầu thả các trang cũ khỏi quá trình xử lý.
Bạn có thể hỏi lý do tại sao Linux tiếp tục phân bổ các trang tối đa 500 MB và không dừng lại sớm hơn nhiều vì chúng được đánh dấu là truy cập tuần tự. Đó là một trong hai hệ thống có đủ các trang bộ nhớ miễn phí, hoặc các trang cư trú khác quá cũ để giữ lại. Giữa việc giữ các trang cổ trong bộ nhớ không còn hữu ích nữa và mang lại nhiều trang hơn để phục vụ một chương trình đang chạy bây giờ, Linux sẽ chọn tùy chọn thứ hai.
Ngay cả khi chúng được đánh dấu là truy cập tuần tự, nó chỉ là một lời khuyên. Ứng dụng có thể vẫn muốn quay lại các trang đó và đọc lại chúng. Hoặc một ứng dụng khác trong hệ thống. Cuộc gọi madvice() chỉ nói những gì bản thân ứng dụng đang làm, Linux xem xét bức tranh lớn hơn.
Có thể có hoặc không có liên quan, nhưng bạn nên biết: bạn có đang sử dụng hệ thống 32 bit hoặc 64 bit không? Bạn có biết rằng bạn không nên mmap 1 GB trong một hệ thống 32-bit? (ngay cả khi bạn đang sử dụng hệ thống 64 bit, bạn có thể lo ngại về tính di động). – Juliano
Tất cả các hệ thống đều là 64bit (với con trỏ tập 64bit và bù) và tôi có thể ánh xạ thành công các tệp 40 GB. Tôi chỉ đun sôi vấn đề xuống 1GB vì mục đích tái tạo. – Dave
@Sven. Có những trường hợp khi sử dụng ánh xạ bộ nhớ là không thể tránh khỏi, ví dụ khi cuộc gọi thư viện yêu cầu vùng bộ nhớ, thay vì tệp. Vì vậy, đề xuất của bạn không hữu ích và không trả lời câu hỏi. Đối với câu trả lời, rõ ràng trên Linux MMAP_SEQUENTIAL là khá nhiều * bị hỏng *. Phần đọc trước hoạt động, phần khôi phục trang không. Và cách duy nhất đề xuất với Linux rằng trên thực tế các trang này là những ứng cử viên tốt là bằng cách unmapping khu vực (và lập bản đồ nó một lần nữa). –