Kích thước bộ nhớ ảo trong top có nghĩa là gì?


124

Tôi đang chạy topđể theo dõi hiệu suất máy chủ của mình và 2 trong số các quy trình java của tôi hiển thị bộ nhớ ảo lên tới 800MB-1GB. Đó có phải là một điều xấu?

Bộ nhớ ảo có nghĩa là gì?

Và oh btw, tôi có trao đổi 1GB và nó hiển thị 0% được sử dụng. Thế là tôi bối rối.

Quá trình Java = 1 máy chủ Tomcat + Máy chủ java daemon của riêng tôi = Ubuntu 9.10 (nghiệp)


Câu trả lời:


142

Bộ nhớ ảo thậm chí không nhất thiết là bộ nhớ. Ví dụ: nếu bộ nhớ quy trình ánh xạ một tệp lớn, tệp thực sự được lưu trữ trên đĩa, nhưng nó vẫn chiếm "không gian địa chỉ" trong quy trình.

Không gian địa chỉ (ví dụ: bộ nhớ ảo trong danh sách quy trình) không tốn bất kỳ chi phí nào; nó không có thật Cột RSS (RES) thực sự là bộ nhớ thường trú. Đó là bao nhiêu bộ nhớ thực của bạn mà một quá trình đang chiếm giữ.

Nhưng ngay cả đó không phải là toàn bộ câu trả lời. Nếu một quá trình gọi fork (), nó sẽ chia thành hai phần và cả hai ban đầu đều chia sẻ tất cả RSS của họ. Vì vậy, ngay cả khi RSS ban đầu là 1 GB, kết quả sau khi chuyển đổi sẽ là hai quá trình, mỗi quy trình có RSS là 1 GB, nhưng bạn vẫn chỉ sử dụng 1 GB bộ nhớ.

Bối rối chưa? Đây là những gì bạn thực sự cần biết: sử dụng freelệnh và kiểm tra kết quả trước và sau khi bắt đầu chương trình của bạn (trên +/- buffers/cachedòng). Sự khác biệt đó là bao nhiêu mới chương trình mới bắt đầu bạn sử dụng bộ nhớ.


2
"Kiểm tra kết quả trước và sau khi bắt đầu chương trình của bạn", cách khác, sử dụng USS (Kích thước cài đặt duy nhất) như được trả về smem.
Hubert Kario

Vì vậy, có một công cụ cung cấp lượng bộ nhớ thực sự đang được sử dụng, các công cụ không phải là bên thứ ba.
CMCDragonkai

@CMCDragonkai Có, miễn phí.
deviantfan

1
Nếu tôi bắt đầu một quá trình java thông qua java -Xmx16g RunLong, nó sẽ dành bộ nhớ 16Gb cho quá trình java, thì trong VIRTđầu, có vẻ như 16Gb đã được tính. Trong trường hợp này, loại bộ nhớ 16Gb này là bộ nhớ được ánh xạ hay ..?
Eric Wang

1
@EricWang, bộ nhớ đó không được ánh xạ. Đó chỉ là một yêu cầu để HĐH dự trữ bộ nhớ có thể cần thiết sau này (có lẽ không bao giờ). (Ít nhất) trên Linux, đây là một cuộc gọi mmap với MAP_NORESERVE và PROT_NONE cờ (xem os :: cuộc gọi pd_reserve_memory anon_mmap: github.com/AdoptOpenJDK/openjdk-jdk11u/blob/... ); không có bộ nhớ thực sự được phân bổ theo mặc định - điều đó chỉ được thực hiện sau đó khi chương trình thực sự cần bộ nhớ để đáp ứng các yêu cầu cấp phát đối tượng.
Juraj Martinka

23

Từ trang đầu (1) man:

o: VIRT  --  Virtual Image (kb)
      The  total  amount  of  virtual  memory  used  by the task.  It
      includes all code, data and shared libraries  plus  pages  that
      have been swapped out.

      VIRT = SWAP + RES.

Trong đó RES có nghĩa là bộ nhớ RESident (bộ nhớ vật lý được sử dụng).

Thật ra điều đó không đúng (nữa). Khi nó nói "hoán đổi", cũng bao gồm các tệp mà chương trình đã ánh xạ vào không gian địa chỉ của nó, có thể thực sự có thể không tiêu thụ RAM thực. Bộ nhớ này được hỗ trợ tập tin nhưng không thực sự trao đổi.

VIRT cũng bao gồm các trang đã được phân bổ nhưng chưa được sử dụng cho bất cứ điều gì. Bất kỳ trang nào trong trạng thái này được ánh xạ tới kernel Zero Page (khái niệm tuyệt vời - bạn nên tìm kiếm nó) để nó hiển thị trong VIRT nhưng thực sự không tiêu tốn bất kỳ bộ nhớ nào.


2
thật thú vị, VIRT = SWAP + RES cũng vậy, tại sao mức sử dụng SWAP của tôi bằng 0, trong khi bộ nhớ ảo cho 2 tiến trình java gần bằng 1GB ??
kapso

về cơ bản là các chương trình hàng đầu .... Hoán đổi: tổng cộng 1048568k, 0k đã sử dụng, 1048568k miễn phí, 505728k được lưu trong bộ nhớ cache
kapso

15
@ user42159 Câu trả lời này là SAI! KHÔNG CÓ 'VIRT = SWAP + RES' trong top người đàn ông! -m : VIRT/USED toggle Reports USED (sum of process rss and swap total count) instead of VIRT. Thật đáng tiếc khi tôi không thể hạ thấp câu trả lời này.
duleshi

3
Câu trả lời này không chính xác. USED ​​= Res + Swap Size (từ Quản lý trường hàng đầu, được truy cập bằng cách nhấn phím f khi ở trên cùng. Cũng từ trang man trên cùng).
Jason S

15

Tôi thấy lời giải thích này từ Mugurel Sumanariu rất rõ ràng:

VIRTlà viết tắt của kích thước ảo của một tiến trình, là tổng bộ nhớ mà nó thực sự đang sử dụng, bộ nhớ mà nó đã ánh xạ vào chính nó (ví dụ: RAM của card màn hình cho máy chủ X), các tệp trên đĩa đã được ánh xạ vào nó (hầu hết thư viện được chia sẻ đáng chú ý) và bộ nhớ được chia sẻ với các quá trình khác. VIRT thể hiện dung lượng bộ nhớ mà chương trình có thể truy cập tại thời điểm hiện tại.

RESlà viết tắt của kích thước lưu trú, là một đại diện chính xác cho bao nhiêu bộ nhớ vật lý thực tế mà một quá trình đang tiêu thụ. (Điều này cũng tương ứng trực tiếp với cột% MEM.) Điều này hầu như sẽ luôn nhỏ hơn kích thước VIRT, vì hầu hết các chương trình phụ thuộc vào thư viện C.

SHRcho biết kích thước VIRT thực sự có thể chia sẻ được bao nhiêu (bộ nhớ hoặc thư viện). Trong trường hợp của các thư viện, nó không nhất thiết có nghĩa là toàn bộ thư viện là cư dân. Ví dụ: nếu một chương trình chỉ sử dụng một vài chức năng trong thư viện, toàn bộ thư viện sẽ được ánh xạ và sẽ được tính trong VIRT và SHR, nhưng chỉ các phần của tệp thư viện chứa các hàm được sử dụng sẽ thực sự được tải vào và được tính theo RES.


Tôi có lẽ chỉ nói lại "VIRT đại diện cho bao nhiêu bộ nhớ mà chương trình có thể truy cập tại thời điểm hiện tại." đến một cái gì đó như "VIRT thể hiện kích thước của toàn bộ không gian địa chỉ của chương trình tại thời điểm hiện tại." OK, vẫn có thể sử dụng đánh bóng. Nhưng vấn đề là, "bao nhiêu bộ nhớ" vẫn có thể mang lại ấn tượng chúng ta đang thảo luận về RAM, khi VIRT không liên quan gì đến không gian RAM. Trên thực tế, các chương trình lớn thường sẽ có kích thước VIRT, đó là một số NHIỀU tổng kích thước RAM của hệ thống - bởi vì VIRT gần như hoàn toàn là các vùng địa chỉ được hỗ trợ tệp (AKA "không phải là RAM").
FeRD

5

Cột VIRT trong đầu ra ps / top gần như không liên quan để đo mức sử dụng bộ nhớ. Đừng lo lắng về nó. Apache tải nặng VIRT so với bộ nhớ RES

https://stackoverflow.com/questions/561245/virtual-memory-usage-from-java-under-linux-too-much-memory- used


Cảm ơn, tôi đã lo lắng và bối rối, bởi vì trong khi mức sử dụng trao đổi là 0%, cột bộ nhớ ảo rất cao. Và tôi cũng chỉ có 1,7 GB trong tổng số 2,7 GB bộ nhớ vật lý được sử dụng, trong khi bộ nhớ ảo có cao không?
kapso

2

Linux hỗ trợ bộ nhớ ảo, nghĩa là sử dụng đĩa như một phần mở rộng của RAM để kích thước hiệu quả của bộ nhớ có thể sử dụng tăng lên tương ứng. Nhân sẽ ghi nội dung của một khối bộ nhớ hiện chưa sử dụng vào đĩa cứng để bộ nhớ có thể được sử dụng cho mục đích khác. Khi nội dung ban đầu là cần thiết một lần nữa, chúng được đọc lại vào bộ nhớ. Tất cả điều này được thực hiện hoàn toàn minh bạch cho người dùng; các chương trình chạy trên Linux chỉ thấy số lượng bộ nhớ lớn hơn hiện có và không nhận thấy rằng các phần của chúng thỉnh thoảng nằm trên đĩa. Tất nhiên, đọc và ghi đĩa cứng chậm hơn (theo thứ tự chậm hơn hàng nghìn lần) so với sử dụng bộ nhớ thực, vì vậy các chương trình không chạy nhanh như vậy. Phần của đĩa cứng được sử dụng làm bộ nhớ ảo được gọi là không gian trao đổi.

Linux có thể sử dụng một tệp bình thường trong hệ thống tệp hoặc phân vùng riêng cho không gian trao đổi. Phân vùng trao đổi nhanh hơn, nhưng việc thay đổi kích thước của tệp hoán đổi sẽ dễ dàng hơn (không cần phải phân vùng lại toàn bộ đĩa cứng và có thể cài đặt mọi thứ từ đầu). Khi bạn biết bạn cần bao nhiêu dung lượng trao đổi, bạn nên đi phân vùng trao đổi, nhưng nếu bạn không chắc chắn, bạn có thể sử dụng tệp hoán đổi trước, sử dụng hệ thống trong một thời gian để bạn có thể cảm nhận được bạn đã trao đổi bao nhiêu cần, và sau đó tạo một phân vùng trao đổi khi bạn tự tin về kích thước của nó.

Bạn cũng nên biết rằng Linux cho phép một người sử dụng một số phân vùng trao đổi và / hoặc trao đổi các tệp cùng một lúc. Điều này có nghĩa là nếu thỉnh thoảng bạn chỉ cần một lượng không gian hoán đổi bất thường, bạn có thể thiết lập một tệp hoán đổi bổ sung vào những thời điểm như vậy, thay vì giữ toàn bộ số tiền được phân bổ mọi lúc.

Một lưu ý về thuật ngữ hệ điều hành: khoa học máy tính thường phân biệt giữa hoán đổi (viết toàn bộ quá trình ra để hoán đổi không gian) và phân trang (chỉ viết các phần có kích thước cố định, thường là vài kilobyte, tại một thời điểm). Phân trang thường hiệu quả hơn và đó là những gì Linux làm, nhưng thuật ngữ Linux truyền thống nói về việc hoán đổi.

Nguồn: http://www.faqs.org/docs/linux_admin/x1752.html


1
Câu trả lời này lan truyền quan niệm sai lầm rằng bộ nhớ ảo giống như hoán đổi hoặc phân trang. Sử dụng đĩa như một phần mở rộng của RAM có trước bộ nhớ ảo. Và có rất nhiều hệ thống (như hầu hết các bộ định tuyến SoHo) có bộ nhớ ảo nhưng không sử dụng đĩa làm phần mở rộng của RAM. (Và đây cũng không phải là câu trả lời cho câu hỏi của OP, vì anh ta không sử dụng bất kỳ hoán đổi nào.)
David Schwartz

2

VIRtualcột trên cùng, đề cập đến siêu không gian (siêu không gian tiêu thụ) của quy trình, mà quá trình có thể không thực sự diễn ra trong thời gian chạy. Có một cột khác RESident, đề cập đến bộ nhớ / không gian vật lý thực tế được phân bổ bởi quá trình, tại thời gian chạy.

Lý do cho sự khác biệt, giữa hai ví dụ, có thể được hiểu bằng ví dụ: nếu quy trình đang sử dụng thư viện nhất định, thì kích thước thư viện, cũng sẽ hỗ trợ cho virtual-size. tuy nhiên, vì chỉ một phần của thư viện sẽ được sử dụng (tức là một số phương pháp được sử dụng), do đó sẽ hỗ trợ resident-size.

Tham khảo thêm thông tin


0

"VIRT" chỉ là không gian địa chỉ, RES là bộ nhớ "thực", nhưng lượng "SHR" (= chia sẻ) của "RES" là một phần của RES được chia sẻ với các quy trình khác. Vì vậy, đối với hầu hết các quy trình, tôi tin rằng bằng cách trừ SHR khỏi RES sẽ mang lại cho bạn dung lượng bộ nhớ thực sự có thể quy cho quy trình cụ thể này.

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.