Windowsの場合、メモリが足りなくなるとページファイルにメモリの中身が退避されますが、HDDのような遅いストレージでは読み書きが終わるまで全体の処理がストップしてしまうため、この処理が頻繁に起こると非常にストレスとなります。また、SSDでは貴重な書き込み回数を浪費してしまいます。
特に仮想マシンではメモリが限られていることが多いのでスワップの処理が頻繁に起こりがちです。
そのため、WindowsのページファイルをホストのRAM上に配置して動作の高速化を図ってみます。
準備
NTFSパーティションをフォーマットするため、ntfs-3gが必要です。
$ sudo dnf install ntfs-3g # Red Hat
$ sudo apt install ntfs-3g # Debian
ホストの設定
このようなスクリプトを用意します。
#!/bin/sh
if [ -e /tmp/vmswap ]; then
exit 1
fi
mkdir /tmp/vmswap
mount -o size=0,noatime -t tmpfs tmpfs /tmp/vmswap
truncate -s 8G /tmp/vmswap/disk.img
loop=$(losetup -b 4096 -Pf --show /tmp/vmswap/disk.img)
parted -s -a optimal ${loop} mklabel gpt mkpart Volume ntfs 0% 100%
mkfs.ntfs -s 4096 -p 256 -H 0 -S 0 -If "${loop}p1"
parted -s ${loop} set 1 msftdata on
losetup -d ${loop}
#!/bin/sh
if [ ! -e /tmp/vmswap ]; then
exit 1
fi
umount /tmp/vmswap
rm -rfv /tmp/vmswap
vmswap-attach
を実行すると/tmp/vmswap/disk.img
にスワップ領域が作成され、vmswap-detach
を実行すると削除されます。
もう少し詳しく解説すると、tmpfs上に8GBのスパースファイルを用意し、そこにGPTのパーティションを切り、NTFSでフォーマットします。
最後にset 1 msftdata on
するのが重要なポイントで、mkfs.ntfs
だけではWindowsはNTFSとして認識してくれませんでした。
systemdで自動起動できるようにユニットファイルを作成しておきます。
[Unit]
Description=Swap space for Windows on KVM
Before=libvirtd.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/vmswap-attach
ExecStop=/usr/local/bin/vmswap-detach
[Install]
WantedBy=multi-user.target
$ sudo systemctl enable --now vmswap
ゲストの設定
作成したスワップ領域をVMのストレージとして追加します。
使わなくなった領域を解放させるため、Discard modeはunmapを選択します。
XMLを編集し、ブロックサイズを4096バイトに設定して完了です。
(論理セクタサイズをページサイズに合わせて4096バイトでフォーマットしているため、これをしないとWindowsから見えない)
<disk type="file" device="disk">
<driver name="qemu" type="raw" cache="writethrough" io="io_uring" ioeventfd="on" discard="unmap" iothread="4" detect_zeroes="off" packed="on"/>
<source file="/tmp/vmswap/disk.img"/>
<backingStore/>
<!-- ブロックサイズを4096バイトに設定 -->
<blockio logical_block_size="4096" physical_block_size="4096"/>
<target dev="vdb" bus="virtio"/>
<address type="pci" domain="0x0000" bus="0x08" slot="0x00" function="0x0"/>
</disk>
次に、ページファイルを置くための設定をします。
Windowsを起動したら、スタートボタンを右クリック→システム→関連設定の「システムの詳細設定」→詳細設定タブ→パフォーマンスの「設定」→詳細設定タブ→仮想メモリの「変更」をクリックします。
すると仮想メモリの設定ウィンドウが表示されます。
設定後の画面がこちらです。
Dドライブが先程追加したストレージです。
カスタムサイズの場合、空き領域から5MB引いた8124MBが最大でこれ以上は大きくできません。
ここではストレージの領域を最初から目一杯使うように設定していますが、通常はシステム管理サイズで問題ないと思います。
入力後は必ず「設定」ボタンを押さないと反映されないので忘れずにクリックしておきます。
再起動後、追加した領域が仮想メモリとして反映されているのが確認できます。