배포판에서 이식 가능한 사용 가능한 메모리 양을 얻는 방법은 무엇입니까?

배포판에서 이식 가능한 사용 가능한 메모리 양을 얻는 방법은 무엇입니까?

메모리를 보고하는 표준 파일/도구는 Linux 배포판에 따라 형식이 다른 것 같습니다. 예를 들어 Arch 및 Ubuntu에서.

  • 아치

    $ 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
    
  • 우분투

    $ 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
    

그렇다면 특정 시간에 소프트웨어에서 사용할 수 있는 메모리 양(스왑 제외)을 이식하고(Linux 배포판에만 해당) 안정적으로 확보하려면 어떻게 해야 합니까? 아마도 이것은 freeArch 및 Arch의 출력에 "Available" 및 "MemAvailable"로 표시되는 것이지만 cat /proc/meminfoUbuntu나 다른 배포판에서 동일한 결과를 얻으려면 어떻게 해야 합니까?

답변1

MemAvailable/proc/meminfo커널 버전 3.14부터 포함되었습니다.34e431b0a 제출. 이것이 표시되는 출력 변화의 결정 요인입니다. 커밋 메시지는 다음 없이 사용 가능한 메모리를 추정하는 방법을 나타냅니다 MemAvailable.

현재 시스템을 스왑으로 푸시하지 않고 새 작업 부하에 사용할 수 있는 메모리 양은 MemFree, Active(file), Inactive(file)SReclaimable의 "낮은" 워터마크를 기반으로 추정 할 수 있습니다 /proc/zoneinfo.

낮은 워터마크는 시스템 전환 수준입니다. 따라서 가 없으면 최소한 MemAvailable, 및 에서 제공하는 값 중 에 있는 값을 더하고 그 값에서 최저 워터마크를 뺄 수 있습니다. 후자는 또한 각 영역에 사용 가능한 페이지 수를 나열하므로 비교에 도움이 될 수 있습니다.MemFreeActive(file)Inactive(file)SReclaimable/proc/meminfo/proc/zoneinfo

전체 알고리즘은 패치에 제공되며 meminfo.c적응하기가 상당히 쉬운 것 같습니다.

  • 모든 영역에 낮은 워터마크를 추가합니다.
  • 식별된 여유 메모리( MemFree)를 가져옵니다.
  • 낮은 워터마크 빼기(교환을 피하기 위해 만지지 않아야 함)
  • 페이지 캐시에서 사용할 수 있는 메모리 양을 더합니다( 및 Active(file)) Inactive(file). 이는 페이지 캐시에서 사용하는 메모리 양에서 페이지 캐시의 절반이나 로우 워터마크 중 더 작은 쪽을 뺀 값입니다.
  • SReclaimable동일한 알고리즘을 따르면 회수할 수 있는 메모리 양이 추가됩니다( ).

따라서 이 모든 것을 종합하면 다음과 같은 방법으로 새 ​​프로세스에 사용할 수 있는 메모리를 얻을 수 있습니다.

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 

답변2

Stephen의 답변은 매우 적절하고 주의가 부족하지만 최소한의 비교를 포함하여 전체 논리를 기록하기로 결정했습니다. 정보는 먼저 /proc/meminfo에서 읽혀지고 메모리 세부 사항의 일관성을 유지하기 위해 변수에 저장됩니다.

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

변수에 저장된 결과는 바이트 단위입니다.

관련 정보