다음 시나리오를 상상해 보십시오. 2GiB가 zram으로 교체되고 1GiB로 압축됩니다.
메모리 압박이 완화되고 2GiB가 스왑 불가능해지면 Linux에서 압축된 zram 페이지를 저장하는 데 사용되는 1GiB 페이지를 확보할 수 있습니까?
그렇다면 기존 페이지 조각 모음이 수행됩니까?
압축된 페이지에는 여러 페이지가 있어야 합니다. 한 페이지만 남기고 모두 교체되지 않으면 어떻게 되나요? 마지막 페이지도 해제될 때까지 모든 페이지가 메모리에 유지됩니까?
답변1
기본적으로 '아니오'라고 말하겠지만 그렇게 해도 괜찮습니다.
$ lsblk --discard /dev/zram0
NAME DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
zram0 0 4K 2T 0
이것은 zram0
일회용 장치를 의미합니다.
~에서man swapon
:
-d
,--discard[=policy]
스왑 폐기 활성화,스왑 지원 장치가 삭제 또는 정리 작업을 지원하는지 여부.
[...]
마운트/etc/fstab
옵션discard
,discard=once
또는discard=pages
을 사용하여 폐기 플래그를 활성화할 수도 있습니다.
특정 Linux 배포판에서 명령 또는 이에 상응하는 명령이 실행되는 위치를 파악 swapon
하고 그에 따라 추가하면 됩니다.교환 --discard
옵션 또는산 discard
이 장소의 옵션(또는 최소한 =pages
변형)입니다 .
답변2
짧은 답변: 네, zram 배경 페이지가 자동으로 공개됩니다.
실험적 확인(커널 5.10.105) 결과, zram 장치를 사용하지 않는 경우에도 사용되지 않은 zram 저장소가 자동으로 해제되는 것으로 보입니다 discard
.
요약:다음 스크립트는 많은 양의 메모리를 할당하는 프로세스를 실행합니다.
검사를 통해 zram 사용량이 zramctl
처음에는 증가하다가 프로세스를 중지하고 스왑 페이지를 제거한 후 기준선으로 돌아갑니다.
# * I've run this on a freshly booted VM *
# zram is mounted with nodiscard to exclude any effects of
# `discard`.
sudo grep zram /etc/fstab
# /dev/zram0 none swap nodiscard,pri=5
# We have ~6 GiB of RAM
grep -i memtotal /proc/meminfo
# MemTotal: 6386852 kB
# Show zram usage.
# `DATA` is the total amount of uncompressed data currently stored in zram.
zramctl
# NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
# /dev/zram0 zstd 3.1G 4K 58B 4K 4 [SWAP]
# Start a process that allocates 10 GiB of RAM
stress-ng -- --vm-bytes $((10*1024**3)) --vm-keep --vm 1 &
# *Wait some time for the stress test command to be swapped out*
# zram usage has gone up from 4 KiB to 3.1 GiB
zramctl
# NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
# /dev/zram0 zstd 3.1G 3.1G 1.1G 1.2G 4 [SWAP]
# Stop stress test
kill %1
# zram usage decreased from 3.1 GiB to 0.3 GiB
zramctl
# NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
# /dev/zram0 zstd 3.1G 336.8M 48.6M 57.6M 4 [SWAP]
# Read the first byte of all memory pages of all processes.
# This evicts all non-kernel swapped pages without using `swapoff`, which might
# reset the zram device.
sudo ./read_all_mem_pages.rb
# Now zram usage is almost back to zero
zramctl
# NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
# /dev/zram0 zstd 3.1G 18.4M 3.5M 5.9M 4 [SWAP]
원천 read_all_mem_pages.rb
:
#!/usr/bin/env ruby
def access_all_pages(pid)
name = File.basename(File.readlink("/proc/#{pid}/exe")) rescue return
puts "#{pid} (#{name})"
File.open("/proc/#{pid}/mem", 'r') do |mem|
for_each_mem_page(pid) do |page_address|
mem.seek(page_address)
mem.read(1) rescue nil
end
end
end
def for_each_mem_page(pid)
File.foreach("/proc/#{pid}/maps") do |line|
fields = line.split
range, dest = fields[0], fields[-1]
next if dest == "[vsyscall]"
start, end_ = range.split('-').map { |x| x.to_i(16) }
address = start
while address < end_
yield address
address += 4096
end
end
end
pids = Dir.children('/proc').grep(/^\d+$/).map(&:to_i)
pids.each { |pid| access_all_pages(pid) }
답변3
나는 zRam이 소비하는 메모리가 결코 해제되지 않는다고 믿습니다. 바라보다
sudo zramctl --output-all
NAME DISKSIZE DATA COMPR ALGORITHM STREAMS ZERO-PAGES TOTAL MEM-LIMIT MEM-USED MIGRATED MOUNTPOINT
/dev/zram0 5,4G 56,6M 26,5M lz4 2 697 28,2M 0B 28,2M 0B [SWAP]
중요한 것은 "TOTAL"의 증감이 아니라 제가 테스트한 한 절대 감소하지 않는 "MEM-USED"입니다. (0으로 되돌리려면 zramswap.service를 다시 시작해야 했습니다). "--output-all" 스위치를 사용하여 zramctl에서 "MEM-USED" 필드만 가져올 수 있습니다.