자주 메모리가 부족해지는 데스크탑 시스템을 실행하고 있는데, 이로 인해 조사가 필요해졌습니다.무엇처음에 이 문제를 일으켰습니다.
문제는 어떤 프로세스도 메모리를 소비하지 않지만 시스템에서는 이를 사용 가능한 것으로 표시하지 않는다는 것입니다. 게다가 시스템이 스왑을 수행하므로 메모리 압박이 실제인 것처럼 보입니다. 이상한 점은 로그아웃했다가 다시 돌아오면 사용량이 정상으로 돌아가서(~1GB 사용) 메모리 누수보다는 사용자 공간과 커널 사이의 이상한 상호 작용처럼 보인다는 것입니다.
간단히 말해서:
- 캐시/버퍼를 제외한 보고된 메모리 사용
free
: 3173960kB - 모든 애플리케이션의 총 USS: 2413952kB
- SLAB 크기: 158968kB
- zram(압축): 75992kB
이는 3173960-2413952-158968-75992 = 525048 kB
계산되지 않은 메모리 사용량을 제공합니다.
내가 무엇을 놓치거나 계산하지 않았습니까?
총 애플리케이션 메모리 사용량:
# smem -t | sed -n '1p;$p'
PID User Command Swap USS PSS RSS
108 6 244524 2413952 2461340 2648488
보고된 메모리 사용량 free
:
# free -k
total used free shared buffers cached
Mem: 4051956 3449748 602208 0 26548 249240
-/+ buffers/cache: 3173960 877996
Swap: 4051952 242592 3809360
일반 메모리 통계:
# cat /proc/meminfo
MemTotal: 4051956 kB
MemFree: 612260 kB
Buffers: 26636 kB
Cached: 249304 kB
SwapCached: 107892 kB
Active: 1774004 kB
Inactive: 885268 kB
Active(anon): 1712484 kB
Inactive(anon): 710788 kB
Active(file): 61520 kB
Inactive(file): 174480 kB
Unevictable: 9332 kB
Mlocked: 9332 kB
SwapTotal: 4051952 kB
SwapFree: 3809368 kB
Dirty: 40 kB
Writeback: 0 kB
AnonPages: 2343292 kB
Mapped: 95288 kB
Shmem: 36396 kB
Slab: 158968 kB
SReclaimable: 53900 kB
SUnreclaim: 105068 kB
KernelStack: 3528 kB
PageTables: 43600 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 6077928 kB
Committed_AS: 4013288 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 139852 kB
VmallocChunk: 34359570976 kB
HardwareCorrupted: 0 kB
AnonHugePages: 641024 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 2310848 kB
DirectMap2M: 1882112 kB
스왑이 열려있습니다 zram
:
# cat /proc/swaps
Filename Type Size Used Priority
/dev/zram0 partition 2025976 121252 100
/dev/zram1 partition 2025976 121324 100
# awk ' { print $0 / 1024; sum+=$0 } END { print "sum:" sum/1024 } ' /sys/block/zram*/compr_data_size
37962.4
38030.1
sum:75992.5
답변1
질문
4GB RAM(물리적 메모리) 및 최대 2,025,976kB(각각 약 2GB)의 zram 장치 2개가 있습니다. zram은 사용 가능한 메모리를 사용하고 있으며 내부적으로 무슨 일이 일어나고 있는지 정확히 모르지만 메커니즘이 무엇이든 시나리오를 명확하게 상상할 수 있습니다. Linux 페이징 아웃(= RAM의 일부 메모리를 zram에 추가)을 통해 더 많은 여유 공간을 확보하고 그런 다음 zram 사용 메모리의 메모리가 계속 증가하므로 더 많이 페이징되어 zram 사용량이 더 증가하고 zram이 모든 물리적 메모리를 소진할 때까지 계속됩니다.
위에서 언급한 것처럼 페이징이 커널에 스트레스를 주지 않는 모든 시스템에는 임계값이 있으므로 zram이 성능을 향상시킬 수 있다고 생각합니다.
의견
시스템이 100MB를 교환하려고 하면 100MB가 zram에 저장됩니다. 50%, 즉 50MB로 압축되었다고 가정해 보겠습니다. 이는 시스템에서 100MB를 확보하려고 했지만 50MB만 확보되었음을 의미합니다. 이제 Linux는 메모리 조각을 페이지 아웃할 때(따라서 스왑에 넣음) 메모리가 다시 필요할 때 해당 메모리를 다시 페이징할 수 있지만 스왑에 보관할 수도 있는 "최적화"를 수행할 수 있다는 점에서 똑똑합니다. 메모리의 해당 부분을 곧 페이지 아웃해야 하는 경우 스왑 파일에 대한 비용이 많이 드는 쓰기를 피할 수 있습니다. 따라서 귀하의 경우 Linux는 zram에 100MB를 유지하고 다시 일반 RAM에 넣을 수 있으므로 시스템은 일시적으로 150MB를 소비합니다. 압축 가능한 데이터가 적은 대규모 프로그램에 대해 이것이 반복되면 이는 빠르게 악몽이 될 수 있습니다. 페이지 아웃되는 300MB RAM 블록과 각 zram 스왑에 120MB가 사용되는 것을 상상해 보십시오. 이는 Linux가 다른 목적을 위해 300MB의 RAM을 확보하려고 했지만 60MB만 확보한 경우(300-120-120=60) 더 많은 페이지를 페이지 아웃하려고 시도할 수 있다는 것을 의미합니다. 문제는 다음과 같습니다. 2개의 zram, 각 zram은 최대 2GB의 RAM을 사용할 수 있으므로 메모리를 모두 소모합니다.
결론 및 해결책
그럼 zram은 쓰레기인가요? 아니요, 전혀 아닙니다. 문제는 zram을 물리적 RAM과 정확히 동일한 전체 크기를 갖도록 구성했다는 것입니다. 그게 문제입니다. IMHO 물리적 RAM의 25% 이상을 사용하도록 zram을 구성하면 안 됩니다. 즉, zram 스왑이 채워지면 하드 드라이브 스왑 솔루션에 계속 의존해야 한다는 의미입니다.
간단한 해결책은 zram을 줄여 각각 최대 500MB를 처리하고 약 2-3GB의 스왑 파일을 추가하여 커널이 실제로 사용되지 않은 페이지를 zram에서 이 스왑 파일로 릴리스할 수 있도록 하는 것입니다. 스왑 파일은 RAM을 사용하지 않으므로 RAM에 대한 부담이 줄어듭니다.
몇가지 정보zram 디스크 크기를 설정하는 방법.
답변2
smem
실제로 사용된 메모리를 볼 수 있지만 "시스템" 모드에서만 가능하다는 것을 알았습니다 .
# smem -tw
Area Used Cache Noncache
firmware/hardware 0 0 0
kernel image 0 0 0
kernel dynamic memory 1200240 379444 820796
userspace memory 2101184 136800 1964384
free memory 750532 750532 0
----------------------------------------------------------
4051956 1266776 2785180
# free -k
total used free shared buffers cached
Mem: 4051956 3298200 753756 0 31664 425552
-/+ buffers/cache: 2840984 1210972
Swap: 4051952 237368 3814584
free
이로 인해 캐시되지 않은 메모리와 사용된 메모리 간에 약 55MiB의 차이가 발생합니다 smem
.
답변3
이 free -tm
명령은 tmpfs가 지원하는 파일의 스왑 사용량도 표시합니다. 폴더를 비울 수 있다면 /tmp
메모리 사용량은 smem -t -k
비슷할 것입니다 free -tm
.