2010-09-24 34 views
5

Tôi có một vấn đề đã được mô tả trong nhiều chủ đề liên quan đến bản đồ bộ nhớ và tiêu thụ bộ nhớ ngày càng tăng trong Linux.Linux Bộ nhớ ánh xạ tập tin dự trữ rất nhiều bộ nhớ vật lý

Khi tôi mở một tập tin 1GB dưới Linux hoặc hệ điều hành MacOS X và bản đồ nó vào bộ nhớ sử dụng

me.data_begin = mmap(NULL, capacity(me), prot, MAP_SHARED, me.file.handle, 0); 

và tuần tự đọc bộ nhớ ánh xạ, chương trình của tôi sử dụng hơn và căng thẳng hơn bộ nhớ mặc dù tôi đã sử dụng posix_madvise (thậm chí gọi nó nhiều lần trong quá trình đọc):

posix_madvise(me.data_begin, capacity(me), MMAP_SEQUENTIAL); 

không thành công. :-(

tôi đã cố gắng:

  • cờ khác nhau MMAP_RANDOM, MMAP_DONTNEED, MMAP_NORMAL không thành công
  • posix_fadvise (me.file.handle, 0, công suất (tôi), POSIX_FADV_DONTNEED) trước và sau khi gọi mmap -> không thành công

làm việc trên Mac OS X !!! khi tôi kết hợp

posix_madvise(.. MMAP_SEQUENTIAL) 

msync(me.data_begin, capacity(me), MS_INVALIDATE). 

Bộ nhớ thường trú dưới 16 triệu (Tôi định kỳ gọi msync sau bước 16mio).

Nhưng dưới Linux không hoạt động. Có ai có một ý tưởng hoặc một câu chuyện thành công cho vấn đề của tôi trong Linux?

Chúc mừng, David

+0

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

+0

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

+0

@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). –

Trả lời

8

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.

+0

Cảm ơn Juliano, rằng hành vi 50% thú vị. Tôi tự hỏi tại sao không có cách nào để thực thi Linux để các trang miễn phí mà tôi không bao giờ đọc lại. Thay vào đó nó hy sinh các bộ đệm và cache của hệ thống tệp. Trên MacOS X, hãy hy sinh các vùng đệm này cho đến khi hoàn toàn không sử dụng được. Nhưng may mắn thay chúng ta có thể ngăn chặn điều đó thông qua * msync (... MS_INVALIDATE) * Trên Linux nó có vẻ là hành vi bạn quan sát với madvice ngăn cản hệ thống ngừng hoạt động. – Dave

+1

@Dave: hãy xem xét rằng không có vấn đề gì với các trang miễn phí quá sớm. Linux không hy sinh bộ đệm và bộ đệm, thay vào đó, nó đang làm chính xác điều đó. Khi bạn đọc thêm dữ liệu từ đĩa, Linux phải mang chúng đến bộ nhớ anyways. Nó sắp xếp các cache được đọc từ đĩa, nhưng thay vì tính toán nó như là "cache", nó ghi lại nó như một phần của RSS của quá trình đã ánh xạ tập tin đó. Khi Linux cần bộ nhớ cache một lần nữa, nó sẽ miễn phí các trang được ánh xạ tới ứng dụng đó. Bạn không cần phải lo lắng về điều đó! – Juliano

+0

@Juliano: hãy xem xét rằng MADV_SEQUENTIAL đặc biệt cho hệ thống biết rằng các trang sẽ được truy cập thông qua chỉ đọc tuần tự một lần. Những trang này là những ứng cử viên hoàn hảo để đòi lại.Thay vào đó, tôi thấy rằng trên hộp của tôi, cho đến khi 50% bộ nhớ (32GB trong trường hợp đó) đạt được, bộ nhớ cache tập tin đang được khai hoang. Và tôi thấy rằng việc thực hiện các quy trình khác đang xuống cấp, Bây giờ tôi đã tìm thấy một cách ridiculus buộc Linux không làm điều đó. Bằng cách unmapping và lập bản đồ các tập tin một lần nữa, mỗi 1Gb hay như vậy. Điều đó * DOES * giải quyết vấn đề và sau đó tôi không thấy sự xuống cấp performace cho các quá trình khác. –

Các vấn đề liên quan