Làm cách nào tôi có thể nhận được số lượng bộ nhớ khả dụng trên các bản phân phối?


12

Các tệp / công cụ tiêu chuẩn báo cáo bộ nhớ dường như có các định dạng khác nhau trên các bản phân phối Linux khác nhau. Ví dụ: trên Arch và Ubuntu.

  • Cổng vòm

    $ free
                  total        used        free      shared  buff/cache   available
    Mem:        8169312     3870392     2648348       97884     1650572     4110336
    Swap:      16777212      389588    16387624
    
    
    $ head /proc/meminfo 
    MemTotal:        8169312 kB
    MemFree:         2625668 kB
    MemAvailable:    4088520 kB
    Buffers:          239688 kB
    Cached:          1224520 kB
    SwapCached:        17452 kB
    Active:          4074548 kB
    Inactive:        1035716 kB
    Active(anon):    3247948 kB
    Inactive(anon):   497684 kB
    
  • Ubuntu

    $ free
                 total       used       free     shared    buffers     cached
    Mem:      80642828   69076080   11566748    3063796     150688   58358264
    -/+ buffers/cache:   10567128   70075700
    Swap:     20971516    5828472   15143044
    
    
    $ head /proc/meminfo 
    MemTotal:       80642828 kB
    MemFree:        11565936 kB
    Buffers:          150688 kB
    Cached:         58358264 kB
    SwapCached:      2173912 kB
    Active:         27305364 kB
    Inactive:       40004480 kB
    Active(anon):    7584320 kB
    Inactive(anon):  4280400 kB
    Active(file):   19721044 kB
    

Vì vậy, làm thế nào tôi có thể di chuyển một cách hợp lý (chỉ trên các bản phân phối Linux) và đáng tin cậy để có được số lượng bộ nhớ mà không bao gồm hoán đổi có sẵn để phần mềm của tôi sử dụng tại một thời điểm cụ thể? Có lẽ đó là những gì được hiển thị là "khả dụng" và "MemAv Available" trong đầu ra của freecat /proc/meminfotrong Arch nhưng làm cách nào để tôi có được điều tương tự trong Ubuntu hoặc bản phân phối khác?

Câu trả lời:


18

MemAvailableđược bao gồm trong /proc/meminfophiên bản 3.14 của kernel; nó đã được thêm vào bởi cam kết 34e431b0a . Đó là yếu tố quyết định trong các biến thể đầu ra mà bạn hiển thị. Thông báo cam kết cho biết cách ước tính bộ nhớ khả dụng mà không cần MemAvailable:

Hiện nay, dung lượng bộ nhớ có sẵn cho một khối lượng công việc mới, mà không đẩy hệ thống vào trao đổi, có thể được ước tính từ MemFree, Active(file), Inactive(file), và SReclaimable, cũng như "thấp" watermarks từ /proc/zoneinfo.

Các hình mờ thấp là mức mà hệ thống sẽ trao đổi. Vì vậy, trong sự vắng mặt của MemAvailablebạn ít nhất có thể gắn lên các giá trị đưa ra cho MemFree, Active(file), Inactive(file)SReclaimable(bất cứ là trong hiện tại /proc/meminfo), và trừ các hình mờ thấp từ /proc/zoneinfo. Cái sau cũng liệt kê số lượng trang miễn phí trên mỗi vùng, có thể hữu ích khi so sánh ...

Thuật toán hoàn chỉnh được đưa ra trong bản vá để meminfo.cvà có vẻ dễ dàng thích nghi:

  • tổng các hình mờ thấp trên tất cả các vùng;
  • lấy bộ nhớ miễn phí đã xác định ( MemFree);
  • trừ hình mờ thấp (chúng ta cần tránh chạm vào đó để tránh tráo đổi);
  • thêm dung lượng bộ nhớ chúng ta có thể sử dụng từ bộ đệm trang (tổng Active(file)Inactive(file)): đó là dung lượng bộ nhớ được sử dụng bởi bộ đệm trang, trừ một nửa bộ đệm trang hoặc hình mờ thấp, tùy theo mức nào nhỏ hơn;
  • thêm số lượng bộ nhớ chúng ta có thể lấy lại ( SReclaimable), theo cùng một thuật toán.

Vì vậy, kết hợp tất cả những thứ này lại với nhau, bạn có thể có được bộ nhớ khả dụng cho một quy trình mới với:

awk -v low=$(grep low /proc/zoneinfo | awk '{k+=$2}END{print k}') \
 '{a[$1]=$2}
  END{ 
   print a["MemFree:"]+a["Active(file):"]+a["Inactive(file):"]+a["SReclaimable:"]-(12*low); 
  }' /proc/meminfo 

Ah, tốt, vì vậy ít nhất nó phải được di động trên cùng một phiên bản kernel. Đó là một cái gì đó. Tôi đang kiểm tra đề xuất của bạn awk -v low=$(grep low /proc/zoneinfo | awk '{k+=$2}END{print k}') '{a[$1]=$2}END{m=a["MemFree:"]+a["Active(file):"]+a["Inactive(file):"]+a["SReclaimable:"]; print a["MemAvailable:"],m-low}' /proc/meminfođể cung cấp cho tôi cùng một số được in hai lần. Tuy nhiên, số thứ hai (sự hiểu biết của tôi về thuật toán mà bạn đề xuất) cao hơn số MemAvailableđược hiển thị trong /proc/meminfo. Tôi đang làm gì sai?
terdon

2
/proc/zoneinfođếm các trang, có kích thước chủ yếu là 4KB amd64; bạn cũng đang thiếu sự an toàn bổ sung được thêm vào bộ đệm trang và bộ nhớ có thể phục hồi. Đơn giản hóa cái sau, chúng ta có thể trừ hình mờ thấp ba lần, vì vậy m-12*low(3 × 4KB) cho kết quả chính xác trên hệ thống của tôi. (Đơn giản hóa này đánh giá thấp bộ nhớ có sẵn nếu bộ nhớ cache trang hoặc bộ nhớ có thể khai phá nhỏ hơn gấp đôi so với watermark thấp, nhưng bạn sẽ không muốn sử dụng nhiều bộ nhớ trong tình huống đó anyway vì vậy mà có vẻ là một sự thỏa hiệp hợp lý.)
Stephen Kitt

1
@StephenKitt làm thế nào bạn có thể tính toán nó cho các hạt nhân cũ hơn không có mục (file)đích hoặc SReclaimablemục nhập? Trên hộp centos cũ hơn có kernel v 2.6.18-348.16.1.el5xen (per uname -r) đây là đầu ra tôi nhận được: pastebin.com/iFWiM1kX . Tính toán của bạn chỉ kéo MemFreephần
Mitch

@Mitch Tôi không biết, tôi không chắc thông tin có sẵn từ kernel cũ của bạn là đủ để xác định chính xác bộ nhớ khả dụng (trước khi trao đổi).
Stephen Kitt

Cảm ơn tất cả những người đã đóng góp cho chủ đề này, nó là một tài liệu tham khảo tuyệt vời. Tính toán của MemAv Available đã được điều chỉnh một chút trong Linux 4.5. Tuy nhiên, phép tính MemAv Available mới phải luôn cao hơn một chút so với (hoặc có thể giống như) phép tính cũ, vì vậy sẽ an toàn khi sử dụng phép tính cũ trong mọi trường hợp. gitlab.com/procps-ng/procps/issues/42
sourcejedi

7

Trong khi câu trả lời của Stephen là hoàn toàn đủ và có phần sai lầm, tôi quyết định viết ra toàn bộ logic bao gồm các so sánh tối thiểu. Thông tin đầu tiên được đọc từ / Proc / meminfo và được lưu trữ trong một biến để các chi tiết bộ nhớ được nhất quán.

LOW_WATERMARK=$(awk '$1 == "low" {LOW_WATERMARK += $2} END {print LOW_WATERMARK * 4096}' /proc/zoneinfo)

MEMINFO=$(</proc/meminfo)

MEMINFO_MEMFREE=$(echo "${MEMINFO}" | awk '$1 == "MemFree:" {print $2 * 1024}')
MEMINFO_FILE=$(echo "${MEMINFO}" | awk '{MEMINFO[$1]=$2} END {print (MEMINFO["Active(file):"] + MEMINFO["Inactive(file):"]) * 1024}')
MEMINFO_SRECLAIMABLE=$(echo "${MEMINFO}" | awk '$1 == "SReclaimable:" {print $2 * 1024}')

MEMINFO_MEMAVAILABLE=$((
  MEMINFO_MEMFREE - LOW_WATERMARK
  + MEMINFO_FILE - ((MEMINFO_FILE/2) < LOW_WATERMARK ? (MEMINFO_FILE/2) : LOW_WATERMARK)
  + MEMINFO_SRECLAIMABLE - ((MEMINFO_SRECLAIMABLE/2) < LOW_WATERMARK ? (MEMINFO_SRECLAIMABLE/2) : LOW_WATERMARK)
))

if [[ "${MEMINFO_MEMAVAILABLE}" -le 0 ]]
then
  MEMINFO_MEMAVAILABLE=0
fi

Kết quả được lưu trữ trong biến là theo byte.


Trong khi câu trả lời này thực hiện tính toán trong cam kết 34e431b0a, câu trả lời của Stephen Kitt cung cấp ước tính chính xác hơn cho 2 máy trong số 5 máy tôi đã thử nghiệm. Trên tất cả 5 máy, cả hai câu trả lời đều đưa ra ước tính lớn hơn MemAv Available được đọc trực tiếp từ / Proc / meminfo. Có lẽ cách an toàn hơn là lấy số nhỏ hơn giữa 2 và nhân 0,95 hoặc hơn.
chập chững
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.