ページ交換がキャンセルされるとzram無料バックアップページは交換されますか?

ページ交換がキャンセルされるとzram無料バックアップページは交換されますか?

次のシナリオを想像してください。 2GiBがzramに置き換えられ、1GiBに圧縮されます。

メモリの圧縮が軽減され、2GiBがスワップできなくなった場合、Linuxで圧縮されたzramページを保存するために使用される1GiBページを入手できますか?

では、既存のページの最適化は実行されますか?
圧縮されたページには複数のページが必要です。 1ページだけ残してすべて交換できない場合はどうなりますか?最後のページも解放されるまで、すべてのページがメモリに残りますか?

答え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オプションdiscarddiscard=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」フィールドのみを取得できます。

関連情報