WSL、VirtualBox内でファイルを削除しても容量が増えない件

WSLのディスク容量削減完全ガイド

WSL(Windows Subsystem for Linux)内で、Dockerのキャッシュやイメージ、stable diffusionのモデルなど比較的サイズの大きいファイルを削除しても、ホストであるWindowsから見ると一向に容量が削減できていない問題について、最新の解決方法を詳細に説明します。

なぜWSL内でファイルを削除してもWindows側の容量が減らないのか

WSLでは、LinuxファイルシステムはWindowsのファイルシステム上に仮想的に存在します。特にWSL 2では、実際のLinuxカーネルを使用し、ファイルシステムはVHDX(Virtual Hard Disk)ファイル内に格納されます。

主な原因

  1. 動的拡張型VHDXの特性: WSL 2のVHDXファイルは動的に拡張されますが、ファイルを削除しても自動的には縮小されません
  2. ファイルシステムの違い: WSL 2のLinuxファイルシステム(ext4)とWindowsのNTFSでは管理方法が異なります
  3. 削除されたファイル領域の扱い: ファイルを削除すると、その領域は「未使用」としてマークされますが、VHDXファイル自体のサイズは変わりません

WSL 2では、デフォルトで各VHDファイルに最大1TBのディスク容量が割り当てられます(WSLリリース0.58.0以前は512GB、それ以前は256GBでした)。

2025年最新の解決方法

方法1: diskpartを使用した手動圧縮(Windows Home/Pro共通)

この方法はWindows 10/11のすべてのエディションで使用可能です。

ステップ1: WSL 2の完全シャットダウン

重要: 圧縮作業前に必ずWSLを完全にシャットダウンする必要があります。

# PowerShellまたはコマンドプロンプトで実行
wsl --shutdown

または、WSL内から直接シャットダウンすることもできます:

# WSL(Ubuntu等)内で実行
sudo shutdown now

確認方法

wsl --list --verbose

すべてのディストリビューションが「Stopped」状態になっていることを確認してください。

ステップ2: VHDXファイルの場所を特定

VHDXファイルの場所を正確に特定する必要があります。以下のPowerShellスクリプトを使用:

# PowerShellで実行(<distribution-name>を実際のディストリビューション名に置き換え)
(Get-ChildItem -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss | 
    Where-Object { $_.GetValue("DistributionName") -eq 'Ubuntu' }).GetValue("BasePath") + "\ext4.vhdx"

一般的な場所の例:

  • Ubuntu: %USERPROFILE%\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\ext4.vhdx
  • Debian: %USERPROFILE%\AppData\Local\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\ext4.vhdx
  • Docker Desktop: %USERPROFILE%\AppData\Local\Docker\wsl\data\ext4.vhdx

ステップ3: diskpartで圧縮実行

  1. 管理者権限でコマンドプロンプトまたはPowerShellを開く
    • スタートメニューで「cmd」と入力
    • 「管理者として実行」を選択
  2. diskpartを起動
diskpart

「DISKPART>」プロンプトが表示されます。

  1. VHDXファイルを選択
select vdisk file="C:\Users\YourUsername\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\ext4.vhdx"

注意点

  • パスは必ず正確に入力してください
  • パスにスペースが含まれる場合は、ダブルクォーテーションで囲みます
  • パスが長い場合は、一度VHDXファイルを別の場所(例:C:\temp\)にコピーしてから作業することも可能です
  1. 圧縮を実行
compact vdisk

成功すると以下のように表示されます:

100% 完了しました
DiskPart により、仮想ディスク ファイルは正常に圧縮されました。
  1. diskpartを終了
exit

方法2: Optimize-VHDを使用(Windows Pro/Enterprise限定)

Windows ProまたはEnterpriseエディションをお使いの場合、Hyper-Vのコマンドレットが使用できます。

Hyper-V機能の有効化

  1. コントロールパネルプログラムと機能Windowsの機能の有効化または無効化
  2. Hyper-Vにチェックを入れる
  3. PCを再起動

圧縮の実行

# PowerShellを管理者として実行
wsl --shutdown

# VHDXファイルのディレクトリに移動
cd "C:\Users\YourUsername\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState"

# 圧縮実行
Optimize-VHD -Path .\ext4.vhdx -Mode Full

方法3: スパースVHD機能の活用(WSL 2.0.0以降)

WSL 2.0.0以降では、スパース(sparse)VHD機能が利用可能になり、ディスク容量の自動管理が改善されました。

スパースVHDの設定

# スパースモードを有効化
wsl --manage Ubuntu --set-sparse true

# 設定を確認
wsl --manage Ubuntu --get-sparse

注意: スパースモードを有効にした場合、Optimize-VHDコマンドは使用できなくなります。代わりに以下の手順で圧縮します:

# スパースモードを一時的に無効化
wsl --manage Ubuntu --set-sparse false

# diskpartまたはOptimize-VHDで圧縮

# スパースモードを再度有効化
wsl --manage Ubuntu --set-sparse true

圧縮効果を最大化するための事前準備

Linux側での空き領域のゼロ埋め処理

圧縮の効果を最大化するために、削除されたファイルの領域をゼロで埋める処理を行います:

# WSL内で実行(Ubuntu/Debian等)
# 注意: この処理には時間がかかります

# 方法1: ddコマンドを使用
sudo dd if=/dev/zero of=/zero.fill bs=1M
sync
sudo rm -f /zero.fill

# 方法2: fstrimを使用(推奨)
sudo fstrim -v /

fstrimコマンドは、マウントされたファイルシステムの未使用ブロックを破棄し、圧縮効果を大幅に改善します。

出力例

/: 24.5 GiB (26309640192 bytes) trimmed

Dockerの場合の追加クリーンアップ

Docker Desktopを使用している場合:

# 不要なコンテナ、イメージ、ボリュームを削除
docker system prune -a --volumes

# Docker Desktopの設定から「Troubleshooting」→「Purge Data」も実行

VirtualBoxのVDIファイル圧縮方法

VirtualBoxを使用している場合も同様の問題が発生します。以下の手順で解決できます:

ステップ1: ゲストOS内でゼロ埋め

# Linux ゲストOSで実行
sudo dd if=/dev/zero of=/zero.fill bs=1M
sync
sudo rm -f /zero.fill

ステップ2: VBoxManageで圧縮

# コマンドプロンプトで実行
cd "C:\Program Files\Oracle\VirtualBox"
VBoxManage modifymedium --compact "C:\path\to\your\virtualdisk.vdi"

注意: パスにスペースが含まれる場合は、VDIファイルを一時的に別の場所に移動してください。

トラブルシューティング

「Optimize-VHD」が認識されない場合

Windows HomeエディションまたはHyper-Vが有効化されていない場合に発生します。代わりにdiskpartを使用してください。

圧縮後も容量が減らない場合

  1. Export/Import方式を試す
# エクスポート
wsl --export Ubuntu ubuntu-backup.tar
   
# アンインストール
wsl --unregister Ubuntu
   
# 再インポート
wsl --import Ubuntu C:\WSL\Ubuntu ubuntu-backup.tar
  1. wslcompactツールを使用: GitHubで公開されているwslcompactを使用することも可能です。

VHDXファイルが読み取り専用になった場合

突然のシャットダウンや電源障害により、LinuxディストリビューションのVHDが読み取り専用に切り替わることがあります。

修復手順:

# PowerShellで実行
wsl --shutdown
wsl --mount "C:\path\to\ext4.vhdx" --vhd --bare
wsl sudo e2fsck -f /dev/sdc  # デバイス名は環境により異なる
wsl --unmount

WSLオープンソース化による変更点(2025年5月~)

2025年5月19日、MicrosoftはWSLの大部分をオープンソース化しました。これにより:

主な変更点

  1. 透明性の向上: ソースコードがGitHubで公開され、内部動作が確認可能に
  2. コミュニティ貢献: バグ修正や新機能の提案が可能に
  3. 更新頻度の向上: Windows本体から独立した更新により、機能追加が迅速に

オープンソース化されたコンポーネント

  • wsl.exe、wslconfig.exe、wslg.exe(コマンドラインツール)
  • wslservice.exe(WSLサービス)
  • Linuxデーモンプロセス(ネットワーキング、ポートフォワーディング等)

オープンソース化されていないコンポーネント

  • Lxcore.sys(WSL 1用カーネルドライバ)
  • P9rdr.sys、p9np.dll(\wsl.localhost ファイルシステムリダイレクト)

まとめと実行結果

私の環境では、上記の方法により300GBのVHDXファイルを5GBまで圧縮することができました。削減効果は環境により異なりますが、適切な手順を踏むことで大幅な容量削減が可能です。

重要なポイント

  1. 必ずバックアップを取る(特に重要なデータがある場合)
  2. WSLを完全にシャットダウンしてから作業する
  3. ゼロ埋め処理またはfstrimを実行してから圧縮する
  4. 定期的なメンテナンス(年に1-2回程度)を推奨

参考リンク

参考:ext4.vhdxをWSLで複製した記事

タイトルとURLをコピーしました