WSLでファイルを削除してもCドライブが空かない理由と対処法

WSLのファイル削除とVHDX圧縮を分けてWindowsの容量を確認する

WSLのファイル削除とVHDX圧縮を分けてWindowsの容量を確認する

WSL2内でファイルを削除しても、データを保存するVHDXファイルのWindows側の占有量がすぐ減るとは限りません。Linux内の空き領域とWindows側の空き容量は、別の値として確認する必要があります。通常の動的拡張VHDXなら、対象を特定してバックアップを取り、WSLを停止したうえで圧縮することで、未使用領域を回収できる場合があります。

この記事は、Windowsで使う通常のWSL2ディストリビューションを対象にした手順解説です。2026年9月10日に公式資料を確認して作成しており、実データを使った圧縮・復元の試験や、削減量の測定は行っていません。Docker Desktopが管理する仮想ディスクや、スパース属性付きのVHDXは後半の切り分けを確認してください。

Linux内の空き領域と、Windowsの空き容量は別

WSL2(Windows上でLinuxを動かす仕組み)では、Linuxのファイルを ext4.vhdx という仮想ディスクファイルに保存します。動的拡張の仮想ディスクは、データを書き込むとWindows側で使う領域が増えますが、内部のファイルを消したときに同じ分だけ自動で小さくなるとは限りません。Microsoft:WSLのディスク容量管理Microsoft:compact vdisk

たとえば、Linux内では削除したファイルの領域を再利用できるようになっていても、Windowsには大きなVHDXファイルが残っている場合があります。この状態では、Linuxの df で空きが増えても、エクスプローラーのCドライブの空き容量はあまり変わりません。

確認する値 見ているもの 読み違えやすい点
Linuxの dfUsedAvail Linuxファイルシステム内の使用量・空き Windowsの物理ドライブの空きではない
Linuxの dfSize Linuxから見えるファイルシステム容量 その量をWindows側ですでに消費しているわけではない
VHDXのファイルサイズ 仮想ディスクファイルの長さ スパースファイルではディスク上の占有量と異なる
Windowsのドライブ空き容量 そのドライブで実際に利用できる空き 他のアプリやバックアップの増減も含む

削除後と回収後で使用中のデータ量は変わらず、Windows側の空きが増える模式図

図はMicrosoftのcompact vdiskの説明を基にした独自の模式図です。Windows側の割当領域を示し、Linuxの最大容量や実測の回収量は表していません。

容量回収の操作も三つに分けると理解しやすくなります。ファイル削除はLinux内のデータを不要にする操作、TRIM(未使用ブロックを下位の記憶装置へ通知する処理)は不要になった領域を伝える操作、VHDXの圧縮は仮想ディスクの物理的な占有を減らす操作です。fstrimマニュアルMicrosoft:compact vdisk

圧縮前に、どのVHDXが大きいか確認する

WSL2かどうかを調べる

Windows側のPowerShellを開き、次を実行します。WSL内のBashではなく、WindowsのPowerShellから進めると、後の停止操作で作業端末が終了する混乱を避けられます。

# ディストリビューション名とWSLの方式を取り違えないために確認する
wsl --list --verbose
wsl --version

対象の VERSION2 であることを確認します。wsl --version が使えない古い環境では、wsl --help と導入されているWSLの状態を確認してください。Microsoft:WSLの基本コマンド

以下では名前を Ubuntu とします。実際の名前が Ubuntu-24.04 などなら置き換えてください。

Linux内の使用量を確認する

Windows側のPowerShellから、対象を明示して確認できます。

# 既定のディストリビューションに依存しないよう、対象名を指定する
wsl -d Ubuntu -- df -h /

削除したはずなのに Used がほとんど変わらない場合は、先にLinux内のデータを確認します。削除先が想定と違う、別のファイルが増えた、といった状態では、VHDX圧縮だけで問題は解決しません。

なお、/mnt/c/... に置いた通常のファイルはWindows側のCドライブにあります。Linuxのルート領域 / に保存したデータとは置き場所が違うため、どちらを削除したのかも確認してください。

ディストリビューション名と保存先を対応付ける

Windows側のPowerShellで、登録されている名前と保存先を一覧にします。レジストリ(Windowsの設定データベース)を読み取る操作です。

# 名前が似た別ディストリビューションのディスクを選ばないため、対応を確認する
Get-ChildItem 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss' |
    Get-ItemProperty |
    Select-Object DistributionName, BasePath

一覧はWSLを登録したWindowsユーザーで確認します。別アカウントの管理者として開くと、別ユーザーの登録情報を見ることがあります。

対象の BasePath にある ext4.vhdx を確認します。Microsoftもこの登録情報を使う特定方法を案内しています。インストール方法や移動履歴で保存場所が変わるため、ネット記事のパスをそのまま使わないでください。該当ファイルが見つからない場合は、ここで止めて登録先を確認します。Microsoft:VHDXの場所を確認する

確認した実際のパスを、次の変数へ設定します。下記のパスは書式例です。

# 以降の測定で同じファイルを参照するため、確認済みのフルパスを保持する
[string]$VhdPath = 'C:\WSL\Ubuntu\ext4.vhdx'
Get-Item -LiteralPath $VhdPath | Select-Object FullName, Length, Attributes
Get-PSDrive -Name C | Select-Object Name, Used, Free

Length はファイルの長さをバイトで表示します。エクスプローラーのプロパティにある「サイズ」「ディスク上のサイズ」も併せて控えると、占有量の違いを追いやすくなります。VHDXがDドライブにある場合は、Dドライブの空きを測ってください。D上のVHDXを圧縮しても、Cの空きを直接増やす操作にはなりません。

AttributesSparseFileCompressedEncrypted がある場合は、以下の通常手順へ進まず、後述する条件の確認へ進んでください。

バックアップからVHDX圧縮までの手順

対象は、スパース・圧縮・暗号化属性がない、通常の動的拡張WSL2 VHDXです。圧縮前に、データベース、開発サーバー、ビルドなどの書き込み処理を正常終了し、作業中のファイルを保存します。Docker DesktopやWSLへ接続しているエディターも終了し、途中でWSLが起動し直さない状態にします。

対象確認からバックアップ、TRIM、全WSL停止、圧縮、再起動確認までの順序

図は公式コマンド資料を基に整理した操作順です。TRIMでLinuxを起動した後に、再びWSLを停止します。

1. バックアップを作り、読み取れることを確認する

Windows側のPowerShellで実行します。D:\Backups は、十分な空き容量があり、あらかじめ作成した保存先へ置き換えてください。容量不足のCドライブへ大きなバックアップを作ると、さらに空きを減らします。

# 書き込み処理を止めた状態のバックアップを取るため、先にWSLを停止する
wsl --shutdown
wsl --export Ubuntu 'D:\Backups\Ubuntu-before-compact.tar'

wsl --shutdown は対象のUbuntuだけでなく、実行中のすべてのWSLディストリビューションを停止します。共有作業や別ディストリビューションの処理も終えてから実行してください。Microsoft:WSLの基本コマンド

exportが成功したことと、バックアップファイルが存在することを確認します。Windowsの tar が利用できる場合、次で内容の一覧を読めます。

# ファイルの存在だけでなく、アーカイブの一覧が読めるかも確認する
Get-Item 'D:\Backups\Ubuntu-before-compact.tar' | Select-Object Length
tar -tf 'D:\Backups\Ubuntu-before-compact.tar'

一覧が読めることは、アプリやデータの完全な復元保証にはなりません。重要な環境なら、余裕のある保存先へ別名でimportして起動と必要ファイルを確認してから圧縮へ進みます。元のディストリビューションを残したまま確認するため、ここで wsl --unregister は使いません。復元には wsl --import を使えます。次は未使用の名前と新しい保存先へ復元確認用コピーを作る例です。保存先には追加の空き容量が必要です。

# 元の環境を残して復元結果を確認するため、別名・別フォルダーを使う
wsl --import Ubuntu-RecoveryCheck 'D:\WSL\Ubuntu-RecoveryCheck' 'D:\Backups\Ubuntu-before-compact.tar' --version 2
wsl -d Ubuntu-RecoveryCheck -- ls /home

ls /home は確認の入口なので、必要なファイルやアプリも確かめます。外部マウントや /mnt/c のデータは別途バックアップを確認してください。Microsoft:ディストリビューションのimport

2. Linux内の未使用領域を通知する

バックアップが確保できたら、対象ディストリビューション内でTRIMを行います。次はWindows側のPowerShellから、対象のLinuxコマンドを管理ユーザーとして起動する例です。

# 対象のルート領域だけをTRIMし、別マウントの操作を避ける
wsl -d Ubuntu -u root -- fstrim -v /

fstrim は、ファイルシステムが未使用としているブロックを通知します。出力された容量は、そのままCドライブに戻った容量ではありません。処理が非対応、ファイルシステムが読み取り専用、またはI/Oエラーになる場合は、圧縮へ進まず原因を確認します。fstrimマニュアル

3. WSLをもう一度停止する

TRIMのためにディストリビューションを起動したので、Windows側のPowerShellで再び停止します。

# VHDXを使用したまま圧縮しないため、TRIM後に停止状態へ戻す
wsl --shutdown
wsl --list --verbose

対象が Stopped であることを確認します。この後、圧縮が終わるまではUbuntuの端末、Docker Desktop、WSL連携のエディターなどを開き直さないでください。

4. DiskPartで対象を確認してから圧縮する

WindowsのPowerShellを管理者として開き、diskpart を起動します。

# 仮想ディスクの管理操作に必要な権限で起動する
diskpart

DISKPART> の入力待ちになったら、先ほど確認したVHDXのフルパスを指定します。以下はDiskPartのコマンドで、PowerShellのコードではありません。DiskPartの中では $VhdPath は展開されないので、実際のパスを貼り付けます。

select vdisk file="C:\WSL\Ubuntu\ext4.vhdx"
detail vdisk

選択に成功したこと、表示された対象と種類が意図した動的拡張VHDであることを確認します。別のディスク、固定サイズのディスク、使用中の状態なら、ここで止めて確認してください。Microsoft:detail vdisk

対象の確認ができたら、次を入力します。

compact vdisk

Microsoftが示す条件は、動的拡張VHDで、切り離されているか読み取り専用で接続されていることです。この手順ではWSLを停止して、切り離された状態での実行を前提にしています。使用中というエラーが出る場合は強制的に進めず、WSLや関連アプリの再起動を確認します。Microsoft:compact vdisk

完了メッセージを確認してから、DiskPartで exit と入力します。圧縮中はPCを終了させたり、WSLを起動したりしないでください。

5. 容量とLinuxの動作を確認する

圧縮前と同じWindows側のPowerShellで測定します。新しいウィンドウの場合は、確認済みの $VhdPath を再設定してください。

# 同じファイルとドライブを測り、圧縮前後を比較する
Get-Item -LiteralPath $VhdPath | Select-Object FullName, Length, Attributes
Get-PSDrive -Name C | Select-Object Name, Used, Free

VHDXの保存先がDなら、ここでもDを測ります。空き容量はほかの処理でも変動するため、ファイルのサイズとドライブの空きを併せて記録してください。

続いてUbuntuを起動し、必要なファイルやアプリが使えることを確認します。

# Windows側の容量だけでなく、Linuxの再起動も確認する
wsl -d Ubuntu -- df -h /

圧縮に成功しても、dfSize は変わらないことがあります。ここで行ったのはWindows側の物理的な占有の回収であり、Linuxから見える最大容量を小さくする操作ではないためです。

容量が減らない・エラーになるときの切り分け

状態 確認すること 次の対応
Linuxの Used も減っていない 削除した場所、残っているデータ Linux内の使用量を調べる
「使用中」などで圧縮できない WSLやDocker、エディターが再起動していないか 正常終了と停止状態を再確認
SparseFile が付いている スパースVHDの設定・WSLバージョン 通常の圧縮手順から分けて確認
CompressedEncrypted が付いている VHDXや保存先のファイル属性 通常手順を止め、対応条件を確認
完了してもサイズがほぼ同じ 回収可能な領域があるか、対象が正しいか 同じ操作の連打より測定結果を照合
Cの空きが変わらない VHDXがCにあるか、ほかのファイルが増えたか ドライブ全体の使用量も確認

スパースVHDは強制的に切り替えない

スパースファイル(空の領域を物理的に割り当てず扱うファイル)では、見かけのサイズとディスク上の占有量が異なります。WSLの sparseVhd 設定は、新しく作るVHDをスパース化する設定として説明されており、追記するだけで既存のすべてのVHDが直ちに小さくなると考えないでください。Microsoft:WSLの詳細設定

また、WSL 2.5.8でスパースVHDの有効化に潜在的なデータ破損の警告が出た報告があります。これは特定バージョンの報告で、現在のすべての環境の挙動を示すものではありません。自分の環境で警告が出た場合は、強制許可するオプションを足して先へ進めないでください。WSL issue #13075

スパース属性を解除すれば解決するとも限らず、解除処理で空き容量が不足した報告もあります。空きの少ないドライブで設定を行き来することは避け、バックアップと必要容量を確認します。WSL issue #11664

Docker Desktopのデータは管理元を確認する

Ubuntuの端末からDockerを操作していても、Docker DesktopのデータがUbuntuの ext4.vhdx に入っているとは限りません。Docker Desktopには独自の保存領域があるため、今回のUbuntu向け手順を、見つけたDockerのVHDへそのまま適用しないでください。Docker:WSL 2 backend

Dockerのデータが占有している場合は、Docker側で不要なデータを確認し、その管理方式に合った手順を選びます。逆にWSL内へDocker Engineを直接導入している構成では、そのディストリビューション内の保存領域も調査対象になります。

Optimize-VHDや最大容量の変更とは何が違う?

容量回収の方法として、PowerShellの Optimize-VHD を見かけることもあります。これはHyper-Vモジュールのコマンドで、使える環境とモードの前提を確認する必要があります。Microsoft:Optimize-VHD

操作 目的 注意点
compact vdisk 動的VHDの物理サイズを減らす 対象・停止状態・属性を確認する
Optimize-VHD 仮想ディスクの配置を最適化する Hyper-Vモジュールとモードごとの条件がある
最大仮想容量の変更 Linuxに見せる容量上限を変える Windows側の空き回収とは別の操作
ディストリビューションの登録解除 ディストリビューション自体を削除する データが失われるため、容量回収手順の代わりにしない

Optimize-VHD -Mode Full も、VHDXの接続状態によって実際の処理モードが変わります。コマンド名だけで結果が保証されるわけではなく、Microsoftも最適化してもサイズが減らない場合があると説明しています。Microsoft:Optimize-VHD

容量回収の判断では、「Linux内で空いたか」「対象VHDXの占有量が減ったか」「保存先ドライブの空きが増えたか」を分けて確認すると、次に調べる場所が明確になります。対象が特定できない、バックアップが取れない、ディスクエラーが出る場合は、圧縮より先にその問題を解消してください。

コメント

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