ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

C盘空间被wpsystem吃掉:Windows安卓子系统VHDX清理实战

C盘空间被wpsystem吃掉:Windows安卓子系统VHDX清理实战

硬盘空间告急这种事,往往不会提前打招呼。前阵子我主力工作机上 C 盘一路降到个位数 GB,用空间分析工具扫了一遍,占大头的不是缓存、不是休眠文件、也不是那些动辄 20GB 的虚拟机快照,而是一个藏在用户目录深处、名字叫wpsystem 的文件夹——它属于 Windows 上那套安卓子系统,体积已经悄悄长到了三十多个 GB。这个文件夹平时完全 invisibility,不进任务管理器、不在"设置-存储"里单独列项、也不会被系统自带的磁盘清理识别,但它是整套安卓环境的数据总仓库:你装的 App、App 产生的缓存、聊天记录、截图、下载的视频,全都在里面。这篇东西就是把我这几轮清理、重置、离线挂载排查的完整过程摊开讲清楚:wpsystem 里到底装了什么、为什么删掉的东西空间不回来、重置和手动重建该怎么选、以及在不动环境的前提下把它的体积压回去的具体做法。适合两类人看——C 盘被吃掉一块但不知道该删什么的普通用户,和想搞清楚这套安卓环境数据落盘逻辑、愿意动手折腾的进阶用户。

1. 先搞清楚 wpsystem 到底装了什么

1.1 一个文件夹背后其实是一整台"虚拟手机"

很多人第一次看到 wpsystem 这个名字会以为它是系统垃圾目录,顺手就删,结果安卓子系统直接起不来。理解它的定位最直接的方式是打个比方:这个文件夹相当于一台安卓手机的"整块主板加存储芯片",而不是手机里的某个缓存目录。

Windows 上的安卓子系统本质上是一个跑在轻量虚拟化层里的 Android 环境。为了让这套环境里的系统分区、应用数据、用户文件在反复启动之间保持不变,它必须有一个持久化的存储载体。这个载体不是一堆散落的文件,而是一个虚拟磁盘文件(VHDX 格式),落在 wpsystem 目录里,通常叫userdata.vhdx。系统分区镜像、内核之类只读内容放在安装目录里,而所有"会发生改变"的数据——应用安装后的 dex、数据库、缓存、你拍的照片、下载的文件、系统的/data分区——全部被写进这个 vhdx。

所以从 Windows 的视角看,wpsystem 里躺着一个几十 GB 的二进制大文件;从安卓的视角看,那是它自己的/data分区。两边看到的是同一个东西的两种投影。这也解释了一个很关键的现象:你在安卓里删掉 5GB 视频,Windows 这边的 vhdx 文件大小可能一点都不变。后面的清理难点,八成都是从这句话衍生出来的。

顺带说清楚它的典型位置,方便你直接定位:

%LOCALAPPDATA%\Packages\<安卓子系统包目录>\LocalCache\Local\wpsystem\

包目录的名字是一长串带版本哈希的标识,不同机器、不同版本都不一样,所以最省事的找法是打开%LOCALAPPDATA%\Packages,按文件夹大小排序,体积最大的那个基本就是它。别去安装目录里翻,那里是只读的系统镜像,删了会直接损坏环境。

1.2 目录结构与文件构成拆解

wpsystem 目录本身通常很"干净"——文件数量少,但单个文件巨大。常见构成大致是这样几类:

文件/目录作用能否直接删除风险等级
userdata.vhdx虚拟磁盘,承载整个 Android/data分区可删,但等于恢复出厂高
若干.vhd/.vhdx附属文件交换区、临时虚拟盘随主盘一起处理中
日志与诊断残留子系统运行日志、崩溃记录可删低
锁文件/状态标记记录运行状态,防止重复挂载不可随意删中

重点说userdata.vhdx。它是动态扩展类型的虚拟磁盘:初始只有几个 GB,随着数据写入逐步变大,但通常情况下只增不减。这一特性是所有空间问题的根源。动态 VHDX 的扩容以块为单位进行(块大小通常是 32MB 量级,具体取决于创建参数),当安卓侧写入新数据时,虚拟化层分配新块并标记为已用;但当安卓侧删除数据时,文件系统只是在 ext4 的元数据里打了个"这里空闲"的标记,虚拟化层根本不知道这件事,那些块依然算作"已分配"。

这里还有个常被忽略的细节:安卓的/data里有一大块是应用私有目录,路径形如/data/data/<包名>/,普通文件管理器看不到,必须靠系统级工具或者离线挂载才能访问和统计。很多教程让你"在安卓里用文件管理器清缓存",效果有限,正是因为清的只是/storage/emulated/0那层用户可见区域,真正的大头在私有目录里。

1.3 为什么它会悄无声息地膨胀到几十 GB

我把自己这台机器上的占用做了个粗略归因,大致能对上这个比例:

  • 系统基础数据:4~6GB,包含系统应用数据、Dalvik/ART 运行时缓存、系统日志。这部分是刚需,压不下去。
  • 已安装应用本体:每个 App 的 APK 加上解压后的库文件,一个 100MB 的安装包落地后往往占 250~400MB。
  • 应用缓存与数据库:这是最大的变量。短视频类应用缓存 1~3GB 很常见,即时通讯类应用的聊天记录加图片视频,5~10GB 也不稀奇。
  • 媒体与下载:截图、录屏、下载的文件,全部堆在用户可见目录,很多人忘了清。
  • 崩溃日志与 ANR 记录:单条不大,但累积成千上万条之后也是几百 MB 起步。

关键在于,这些增长是静默的。你在 Windows 的"设置 → 存储"里看到一个笼统的"应用和功能"数字,点进去也只会列出 Windows 应用;磁盘清理工具扫不到Packages目录下的这些内容;甚至有些第三方清理软件会把 vhdx 识别成"未知大文件",标个高风险的黄色警告然后不敢动。我见过最极端的情况是一个测试机上装了十几个安卓应用做兼容性验证,半年后 wpsystem 长到 60GB,机器只剩 3GB 可用空间,然后开始出现各种诡异的系统卡顿——那不是性能问题,是磁盘写满了。

提示:如果你装这套安卓环境只是为了偶尔跑一两个特定应用,那么它的空间增长曲线基本等同于"装了多久 × 用得有多勤",最好在装完第二周就看一眼体积,建立个基线,后面变化才看得懂。

2. 处理思路的取舍:重置、删除、还是精修

2.1 三种清理路径的适用边界

真正动这个文件夹之前,先想清楚你要的是什么结果。我把可行的路径归成三类,它们的代价差别很大:

路径一:系统设置里重置。安卓子系统的设置界面里有"重置"选项,本质上就是让系统自己把userdata.vhdx干掉重建。优点是全程图形界面、不需要命令行、出错概率极低;缺点是所有安卓应用和数据一起没,等于恢复出厂,装过的 App 要重装,登录状态要重来。

路径二:手动删除 vhdx 后重启。效果和重置几乎一样,但要求你先彻底关闭子系统、结束残留进程,然后手动删文件。这条路的唯一优势是能顺带清掉一些重置逻辑没覆盖的残留日志,而且当你连设置界面都打不开(子系统起不来)时,这是唯一选择。

路径三:离线挂载 vhdx 做精准清理。把 vhdx 挂到 Windows 或 WSL 里,直接进 ext4 文件系统,按目录大小定位,删掉那些真正占空间的私有数据,然后卸载、压缩。优点是保数据,应用不用重装;缺点是步骤多、有写坏文件系统的风险,而且 Windows 原生读不了 ext4,需要借助 WSL 的内核挂载能力。

我的判断标准很朴素:如果这台机器上的安卓环境只是用来跑几个不重要的应用、登录状态随时可以重建,那就走路径一,十分钟解决,别浪费时间。只有当里面存了不好恢复的东西——比如某些应用的本地聊天记录、本地保存的素材、离线缓存的重要资料——才值得走路径三。中间那条路径二,我一般用在一个特殊场景:子系统已经彻底坏掉,设置界面点不动,只能靠删文件把环境拉回可用状态。

2.2 我的默认选择与理由

我自己主力的那台机器上,走的是"路径一 + 释放后治理"的组合。理由有三点,都是被坑出来的经验。

第一,重置的清理彻底度比手动删文件高。系统自己的重置流程会连带清理注册表状态、应用清单缓存、以及一些藏在包目录其他位置的元数据。手动删 vhdx 有时候会遇到"删完重启后环境重建了,但某些设置还是旧的"这种半吊子状态。

第二,重置的时间成本远低于预期。我实测下来,一次完整重置加环境重新初始化,大约三到五分钟,比手工挂载、定位、删除、卸载、压缩这一整套下来快得多。如果你只是想腾空间,精修的性价比其实不高。

第三,精修最大的价值不是清空间,而是诊断。我第一次走路径三,主要是想知道"这 30GB 到底是什么吃掉的",而不是为了省那点删除时间。挂载进去跑一遍目录统计,看到某个短视频应用的 cache 目录独占 6GB,那一刻你才知道该在安卓侧用什么策略去防它再长回来。这个认知价值,比省下 20 分钟重要得多。

2.3 动手前的四条底线

不管你选哪条路,这四条建议当成硬性前置条件:

第一,先把要保的东西导出来。安卓侧里能通过"共享文件夹"机制和 Windows 打通,把截图、下载、文档复制到 Windows 的某个目录里再动手。这一步五分钟,能省掉后面很多懊恼。

第二,确认子系统已经完全停止,而不只是窗口关了。关闭窗口只是关掉了显示界面,虚拟机进程可能还在跑。任务管理器里能看到一个以虚拟机内存命名的进程,它还在,文件就还在被占用,你删也删不掉、挂也挂不上。这条在下面实操部分会详细讲怎么确认。

第三,别动Packages目录下的其他包目录。里面除了安卓子系统,还有一堆 Windows 应用的数据。误删别的目录,代价可能比你想的清一个子系统大得多。

第四,动手前记下当前配置。子系统设置里的内存分配、开发者模式开关、共享文件夹映射路径这些,重置后都要重设。花三十秒截图,比重配一遍省事。

注意:不要试图把Packages整个目录用目录联接重定向到其他磁盘来"一劳永逸"。这种做法在某些版本更新后会失效,而且一旦出问题,排查成本极高。空间治理的正道是控制增长,不是搬家。

3. 完整实操:从定位到清干净

3.1 第一步:精确定位与占用测量

不要靠肉眼翻目录。用一条 PowerShell 命令把机器上所有虚拟磁盘文件连同体积列出来,一秒钟出结果:

Get-ChildItem -Path "$env:LOCALAPPDATA\Packages" -Recurse -Include *.vhd,*.vhdx ` -ErrorAction SilentlyContinue | Select-Object @{n='SizeGB';e={[math]::Round($_.Length/1GB,2)}}, FullName | Sort-Object SizeGB -Descending | Select-Object -First 10

输出里排第一的那个userdata.vhdx就是目标。顺手把它的完整路径复制下来,后面所有命令都要用。

接着确认子系统是否真的停了。任务管理器里找虚拟化相关的内存进程,或者在 PowerShell 里查:

Get-Process | Where-Object { $_.ProcessName -like '*vmmem*' -or $_.ProcessName -like '*WSA*' } | Select-Object ProcessName, Id, @{n='MemGB';e={[math]::Round($_.WorkingSet64/1GB,2)}}

如果有结果,说明虚拟机还在跑。先通过子系统设置界面里的"关闭"按钮正常关停,等十秒再查一次。正常情况下这个进程会消失。如果它赖着不走,再考虑强制结束——但强制结束的后果是下次启动可能要做一次文件系统检查,慢一点,一般不会坏。

还有一个测量维度值得记一下:把 vhdx 的"文件大小"和"实际占用"分开看。资源管理器里右键属性会同时显示"大小"和"占用空间",两者差得越多,说明内部空洞越多(也就是删了数据但块没回收),这时候压缩操作才有意义。

3.2 第二步:规范关闭子系统(很多人卡在这)

这一步看着简单,实际上是所有失败案例的高发区。常见的翻车姿势有三种:

姿势一:关掉窗口就去删文件。结果是"文件正在使用中,无法删除"。因为窗口关掉不代表虚拟机停机。

姿势二:任务管理器里结束错了进程。有人看到一堆同名进程就全选结束,把宿主侧的服务进程也干掉了,导致下次启动直接报错。

姿势三:用命令行Stop-Process强杀之后立刻挂载 vhdx。这时候文件系统可能还没完成卸载,ext4 的日志没落盘,挂载上去看到的是残缺目录树,甚至直接报结构损坏。

我自己的规范流程是:先在子系统设置里点关闭,等图标从任务栏消失,再等五到十秒,然后用进程查询确认,最后才开始动文件。这套流程让我这两年没再遇到过文件被占用的问题。如果确实遇到无法正常关闭的僵死状态,强杀之后多等三十秒,让虚拟化层把未落盘的数据刷完,再操作文件。

顺带一个容易忽略的点:如果子系统设置了开机自启,你删完文件重启机器,它可能又自动拉起来重新初始化。重置类操作完成后,建议先去设置里把自启关掉,等你确认不需要了再决定。

3.3 第三步:重置与手动重建

走重置路线的话,打开子系统的设置界面,找到系统信息区域里的重置选项,点下去确认。整个过程会自动完成,你只需要等。

想确认它真的干了活,可以在重置前后各跑一次 3.1 里的体积查询命令,对照userdata.vhdx的大小变化。正常情况下它会从几十 GB 掉回几个 GB。

走手动重建路线的话,顺序是:关闭子系统 → 确认进程消失 → 把userdata.vhdx重命名成userdata.vhdx.bak(别急着删,留个后悔药)→ 重启子系统。系统发现没有数据盘,会自动创建一个全新的。等环境初始化完成、确认一切正常后,再把.bak文件删掉。

这里有个细节值得强调:重命名而不是直接删。我踩过一次坑——某次重命名后启动失败,报了个模糊的错误,最后把.bak改回去就恢复了。如果当时是直接删的,那就只能从头重装整个子系统了。改名的成本是一秒钟,价值是保住一个可能还有救的环境。

手动重建后要重做的事情:重新开启开发者模式(如果之前用 adb 连过)、重设共享文件夹映射、重装你需要的应用。如果你有常用的 APK 安装包,建议在 Windows 侧留一份,重装时直接拖进去装,比在安卓里重新下载快得多——这也顺便回答了"为什么不该把重要 APK 只存在安卓环境里"。

3.4 第四步:挂载 vhdx 做深度清理(进阶)

这条路只在你需要保数据、或者想搞清楚空间去向时才值得走。核心难点是:Windows 原生挂载 vhdx 只能看到分区表,读不了 ext4 内容。所以必须借 WSL 的 Linux 内核来做挂载。

前置条件是子系统已完全关闭(老规矩),并且 Windows 侧已经装好 WSL2 环境。

# 在 WSL 里以 bare 模式把 vhdx 挂成裸块设备,不做自动挂载 wsl --mount --vhd "C:\Users\<用户名>\AppData\Local\Packages\<子系统包目录>\LocalCache\Local\wpsystem\userdata.vhdx" --bare

然后在 WSL 里看块设备:

lsblk -f

你会看到新出现的磁盘,通常带几个分区。安卓的数据分区一般是 ext4,也可能是 f2fs(取决于版本)。确认类型后再挂:

sudo mkdir -p /mnt/wsa sudo mount -t ext4 /dev/sdX1 /mnt/wsa

挂上之后就可以做真正的诊断了,这才是这条路的价值所在:按目录大小排序,一眼看出谁在吃空间。

sudo du -h --max-depth=1 /mnt/wsa/data 2>/dev/null | sort -hr | head -20 sudo du -h --max-depth=1 /mnt/wsa/data/data 2>/dev/null | sort -hr | head -20 sudo du -h --max-depth=1 /mnt/wsa/storage/emulated/0 2>/dev/null | sort -hr | head -20

我上次跑出来的结论是:/data/data下某个视频类应用独占 6.2GB,其中 5.8GB 在cache里;/storage/emulated/0/DCIM里躺着 3GB 的录屏文件,是半年前调试时留下的。这两处加起来就把空间问题解释了九成。

清理的时候务必克制,只删这几类:*/cache/*、*/code_cache/*、明确的临时文件、你自己确认不要的媒体文件。不要碰shared_prefs、databases、files这几个目录——那是应用的配置和业务数据,删了轻则重新登录,重则数据永久丢失。也不要碰/data/system、/data/misc这类系统目录。

清完之后按顺序收尾,这一步顺序错了会出问题:

sudo sync sudo umount /mnt/wsa wsl --unmount "C:\...\userdata.vhdx"

或者直接wsl --unmount全卸。一定先 umount 再 unmount vhdx,反过来操作相当于热拔硬盘,文件系统容易留伤。

3.5 第五步:压缩动态磁盘回收空间

删完数据你会发现 vhdx 文件大小还是老样子——这就是 1.2 里说的"只增不减"。要真正把空间还给 Windows,需要做一次离线压缩。前提是vhdx 是动态扩展类型,且当前未被任何进程占用。

用管理员权限开命令行,走 diskpart:

diskpart select vdisk file="C:\Users\<用户名>\AppData\Local\Packages\<子系统包目录>\LocalCache\Local\wpsystem\userdata.vhdx" attach vdisk readonly compact vdisk detach vdisk exit

这一步的执行时间跟文件大小和磁盘速度有关。我这边一个 30GB 的 vhdx,压缩到 12GB 左右,耗时大概七八分钟,期间磁盘会有明显的持续写入,别在这时候干别的重活。

几点实测心得:

  • attach vdisk readonly里的 readonly 很关键,只读挂载能防止压缩过程中被意外写入,安全得多。
  • compact vdisk只对动态磁盘有效。如果 vhdx 是固定大小类型,这条命令会直接告诉你不行,别硬来。
  • 压缩前最好确认文件系统是干净的。如果之前的操作有过强杀或者非正常卸载,先让子系统正常启动一次、正常关闭一次,再压缩。
  • 压缩完启动子系统验证一下,确认能正常进入安卓环境、应用都还在,再决定要不要删那个.bak备份。

4. 常见问题排查实录

4.1 删不掉、占用中、反复重生

症状一:提示文件正在使用,删不掉。

八成是虚拟机进程没退。按 3.1 的查询命令确认,正常关闭流程走一遍。如果子系统设置界面都打不开,那就用任务管理器结束虚拟内存进程,等三十秒再试。还不行就重启一次系统——不是偷懒,是让虚拟化层彻底释放句柄,比重试十次省时间。

症状二:删完重启,文件夹又回来了,体积还很大。

这有两种可能。一是你的删除动作其实没生效(比如删的是.bak之外的副本),二是子系统自启后从某个快照恢复。检查一下是不是开了开机自启,关掉再试。另外注意,某些版本在升级后会保留旧数据盘做迁移,这时候体积不会立刻降下来,需要按 3.3 的手动重建方式处理。

症状三:重置后应用还在,或者应用没了但设置还在。

这是"半重置"状态,通常是重置流程被中断了(比如中途关机)。补救方式就是走手动重建:关闭 → 改名备份 → 重启重建。不要在半重置状态上继续折腾,越折腾越乱。

症状四:挂载 vhdx 时提示文件系统类型未知或者挂载失败。

先确认分区类型。lsblk -f看 FSTYPE 那一列,如果是 f2fs 就不能用-t ext4。如果显示为空,说明分区表读到了但文件系统没识别出来,可能是分区结构特殊(比如包在 super 分区里),这种情况离线挂载就不好使了,得换回重置路线。别在这上面死磕,收益太低。

4.2 重置后应用与数据状态对照

很多人重置前最纠结的就是"到底会丢什么"。我整理了一份实测对照,省得你反复犹豫:

项目重置后状态说明
已安装应用全部清除需重新安装 APK
应用登录状态全部失效需重新登录
应用内本地数据全部清除聊天记录、离线内容均丢失
共享文件夹映射保留(设置项)但需确认路径仍有效
开发者模式开关通常重置为关闭需手动重开
内存分配等性能设置保留或恢复默认视版本而定,建议复查
Windows 侧共享目录里的文件不受影响这就是要提前导出的原因

看到最后一行,你应该明白为什么我把"先导出"放在四条底线的第一条。共享目录里的东西在 Windows 侧,不进 vhdx,重置动不到它们。这个机制本身就是最好的保数据手段。

4.3 常见问题速查表

现象最可能原因处理动作耗时量级
C 盘空间持续下降但找不到大文件wpsystem 内 vhdx 增长按 3.1 定位测量1 分钟
删除安卓文件后 Windows 空间不变动态磁盘未回收块按 3.5 压缩5~10 分钟
无法删除 vhdx虚拟机进程占用正常关闭 + 确认进程1 分钟
子系统启动报虚拟化相关错误系统虚拟化功能未启用检查系统功能开关10 分钟 + 重启
挂载后目录为空或结构异常未正常卸载或强杀后残留放弃挂载,走重置10 分钟
压缩命令报不支持vhdx 为固定大小类型放弃压缩,走重建—
重置后空间没降半重置状态手动改名重建5 分钟

5. 长期治理:把空间管住而不是反复清

5.1 应用数据的搬家策略

反复清理是下策,控制增长才是正解。我总结下来最有效的两件事,都不复杂。

第一件:把大文件往外挪。安卓侧和 Windows 之间有共享目录机制,把下载、截图、录屏的默认保存位置指到共享目录里去。这样产生的内容直接落在 Windows 磁盘上,不进 vhdx,也就不会推高那个文件。代价是访问速度略慢一点,但换来的是空间不再无声膨胀,很划算。

第二件:给高频应用设"定期清缓存"的习惯。短视频、社交、浏览器这三类是缓存大户。它们的缓存目录往往能长到几个 GB,而这些缓存删掉基本不影响功能,只是下次加载慢一点。与其等积到 20GB 再来一次大清理,不如每月花两分钟在应用设置里点一次清缓存。我自己的节奏是每月第一个周末顺手做一遍,五分鐘的事。

顺带说一个不太直观的点:不是所有"清缓存"都有用。有些应用的缓存目录做了硬链接或者写进了数据库,你在应用内点"清除缓存"只删了一部分。真正彻底的做法还是按 3.4 离线挂载后看du结果——数据不会骗人,哪个目录大就清哪个。

5.2 定期维护节奏与监控

我现在给这套环境定了个很轻量的维护节奏,基本不占时间:

每周一次例行检查。跑一条命令看 vhdx 体积,超过预设阈值(我设的是 20GB)就标记一下,看看最近装了什么新应用。

每月一次轻清理。在安卓侧清一轮高频应用的缓存,清掉共享目录里的临时文件。

每季度一次深度体检。关停子系统,走一遍 3.4 的离线挂载,跑du看目录分布,找出异常增长的目录。这一轮通常能发现"某个应用悄悄存了 3GB 日志"这类问题。

每半年一次重建。如果这台机器上的安卓环境本来就不重要,直接重置一次,比什么都干净。我倾向于把它当成一次"重新开始"的机会,顺便淘汰掉那些装了就再没打开过的应用。

关于扇区这一类底层概念,其实在这套流程里用不上,你不需要关心块大小、簇大小这些细节,compact vdisk会自己处理。真正需要你判断的只有三件事:磁盘是不是动态的、文件有没有被占用、操作后有没有验证。这三个判断点守住了,剩下的都是机械步骤。

最后分享一个我自己吃了亏才记住的细节:清理完一定要启动一次验证,别清理完就直接关机器。我有一次压缩完 vhdx 就关机走人,第二天开机子系统起不来,折腾了半天才发现是压缩过程中某个块状态没落盘,而当时如果立刻启动验证,就能在上下文还在脑子里的时候发现问题、快速回滚到.bak。现在我的习惯是:任何对userdata.vhdx的写操作,做完立刻启动、进桌面、开一个应用、关掉、再正常关闭子系统。这一套两分钟,但把"事后才发现"的概率压到了很低。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进