# * 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) }
默认情况下我会说不,但可以这样做。
这意味着
zram0
是一个具有丢弃能力的设备。来自
man swapon
:人们只需要弄清楚执行
swapon
命令或等效命令的特定 Linux 发行版,并在此位置(或至少是变体)相应地添加swapon--discard
选项或mount选项。discard
=pages
简短回答:是的,zram 支持页面会自动释放。
通过实验(内核 5.10.105)检查后,似乎未使用的 zram 存储被自动释放,即使 zram 设备安装时没有
discard
.摘要:下面的脚本运行一个分配大量内存的进程。
zram 使用量(通过 检查
zramctl
)最初会增加,然后在停止进程并驱逐交换页面后回到基线。来源
read_all_mem_pages.rb
:我相信 zRam 消耗的内存永远不会被释放。看
重要的不是增加和减少的“TOTAL”,而是“MEM-USED”,据我测试,它从未下降。(我必须重新启动 zramswap.service 才能将其恢复为零)。您只能使用“--output-all”开关从 zramctl 获取“MEM-USED”字段。