
上周三半夜被一个电话叫起来救火朋友的笔记本 C 盘只剩 3GBWindows 弹窗提示磁盘空间不足连微信都打不开。远程连过去一看罪魁祸首既不是系统更新缓存也不是休眠文件而是一个装了快两年的安卓模拟器光 data 分区就吃掉 58GB。更离谱的是他已经在模拟器里把能卸的应用都卸了、能清的缓存都清了宿主机上的空间却纹丝不动。这就是很多人都会掉进去的坑你在安卓系统里删掉的东西宿主机的虚拟磁盘文件并不会跟着变小。模拟器占用空间太大、data 分区释放不掉本质上不是一个删文件的问题而是一个虚拟机磁盘怎么回收的问题。这篇东西我打算把安卓模拟器 data 分区的空间构成、稀疏磁盘的回收原理、从轻到重的五层清理手段以及我自己踩过的那些坑一次讲透。不管你是刚装模拟器的新手还是手里挂着七八个多开实例的老玩家都能直接照着做。1. 先搞清楚模拟器的磁盘到底被什么吃掉了1.1 一个实例目录里躺着哪些虚拟磁盘打开模拟器的安装目录进到vms这一层你会看到每个实例一个文件夹名字通常跟着序号走比如leidian0、leidian1。进去之后是一堆体积吓人的虚拟磁盘文件常见的有system.vmdk、data.vmdk、sdcard.vmdk、cache.vmdk扩展名也可能是.vdi或者.img取决于模拟器底层用的是哪套虚拟化方案。这几个文件的分工非常明确。system是系统盘相当于手机出厂时烧进去的那块 ROM一般 2 到 4GB基本不会变除非你升级模拟器版本。sdcard是内部存储的外挂部分对应你在文件管理器里看到的内部存储相册、下载、微信接收的文件都在这儿。cache是系统级缓存盘一般不大。真正的大头永远是data也就是数据分区你装的每一个 App、每一次登录、每一条聊天记录、每一份游戏资源包全都在这里落地。这也是为什么很多人发现明明什么都没干data.vmdk就是一路往上涨。因为安卓应用的默认行为就是能存本地就存本地缓存、离线包、日志全都往 data 分区里塞。注意不同模拟器版本的目录结构改得挺勤快有的把sdcard合并进data有的把cache也合进去。判断方法很简单看哪个文件最大、且修改时间最新那个就是承载读写的那块盘。1.2 data 分区为什么永远是一骑绝尘的大户安卓系统里/data是一块被挂载为可读写的分区它下面又分了几个关键子目录每个都是空间杀手。/data/data存的是每个 App 的私有数据包名一个文件夹。微信、抖音这类应用一个就能占几个 G里面塞的是聊天记录数据库、图片视频缓存、语音文件。/data/media/0是内部存储的用户可见部分也就是你在文件管理里能翻到的东西包括Download、DCIM、Android/data。/data/app是应用安装目录APK 解压后的产物放在这儿装得越多占得越多。/data/dalvik-cache是 Android 运行时把 dex 字节码预编译成机器码的产物初次安装时生成体积相当可观。除此之外还有一些容易被忽略的垃圾堆/data/log系统日志、/data/anr应用无响应时的堆栈快照、/data/tombstones原生崩溃现场、/data/system/dropbox系统异常报告、/data/local/tmp临时文件。这些东西单个不大但模拟器跑久了、崩过几次、装过几个来路不明的应用加起来也能吃掉好几个 G。我实测过一个大概两年前建的实例什么都没装就是平时开着刷点东西data分区已经涨到 22GB。用命令一层层扒下去光是几个主流 App 的缓存目录就占了 14GB剩下的是各种残留包名和日志。1.3 文件大小和占用空间差的是哪一口气这个点是最多人想不明白的也是标题里文件大小和占用空间这两个词真正的含义所在。在 Windows 上右键一个文件看属性你会看到两个数字大小和占用空间。对普通文档来说这俩差不多但对虚拟机磁盘文件差距可以非常大。原因是虚拟磁盘采用精简置备thin provisioning的方式创建创建时声明一个逻辑容量比如 32GB但宿主机上只按实际写入量分配物理块。所以你的data.vmdk可能大小显示 32GB占用空间只有 8GB。问题就出在这个机制上。当你在安卓系统里删掉一个 5GB 的文件安卓内核知道那块空间空闲了但宿主机完全不知情——它看到的还是这个块被写过了。虚拟磁盘对应的物理块不会自动归还只有等安卓再次往那个位置写入新数据才会覆盖。结果就是模拟器里显示剩 20GB 可用宿主机上那个文件一点没瘦。想让宿主机真的回收这些块只有两条路一是让虚拟磁盘支持 TRIM/discard 并且在宿主机上真正执行回收二是手动把空闲区域填零再用磁盘工具压缩。绝大多数模拟器压根没把第一条路打通所以只能走第二条。提示判断当前实例是否支持自动回收可以在模拟器里用adb shell df看 data 分区剩余再对比宿主机上data.vmdk占用空间的变化。如果卸载大应用后宿主机文件纹丝不动就说明自动回收没生效。1.4 主流模拟器默认路径与磁盘格式速查下面这张表是我在几台机器上实际翻出来的版本迭代快路径可能微调但大方向一致可以先按这个找找不到就在安装目录搜.vmdk或.vdi。模拟器实例目录大致位置虚拟磁盘常见格式关键文件雷电类安装目录下vms\实例名\.vmdksystem.vmdk、data.vmdk、sdcard.vmdkMuMu 类安装目录下vms\实例名\.vdisystem.vdi、data.vdi夜神类Nox\bin\BignoxVMS\实例名\.vmdk.vboxdata.vmdk、nox.vbox配置逍遥类Microvirt\MEmu\下的实例目录.vmdkdata.vmdk有一点要提前说清楚.vbox那个 XML 配置文件里记录了实例的内存、CPU、硬盘挂载等信息动它之前一定要复制一份。至于.vmdk、.vdi这类镜像理论上可以用通用虚拟化平台的磁盘工具做收缩但各家镜像头有差异能不能成功得试所以我建议的做法是——先复制一份出来在副本上折腾成功了再替换。2. 动手之前先把边界和退路划清楚2.1 哪些能删哪些一碰就得重装清理 data 分区最大的风险不是清不掉而是清过头。我按安全 / 谨慎 / 禁区三档给你列一下这个清单是我自己踩过坑之后总结的。可以放心删的/data/local/tmp下的临时文件、/data/log、/data/anr、/data/tombstones、/data/system/dropbox、/data/system/usagestats、/data/cache。这些要么是日志要么是崩溃快照删掉系统会自动重建最多丢失一点调试信息。需要确认后再删的/data/dalvik-cache删掉没问题但下一次开机所有应用都要重新做一次预编译首次启动会明显变慢低配机器上可能卡到十几分钟得有心理准备。/data/media/0下面的东西是你自己的文件删之前一定自己看一眼。/data/system/里除 dropbox 之外的数据库文件比如账户信息、包管理状态删了可能导致账号掉线、桌面图标错乱。绝对不要碰的/data/misc里面是 Wi-Fi 密码、蓝牙配对、证书存储、/data/property设备属性、序列号相关、/data/data下系统组件的私有数据、/data/app。这几个目录删了轻则配置全丢重则系统起不来直接重装。注意动手前先用adb shell pm list packages -3导出第三方应用列表用adb shell pm list packages -s导出系统应用列表存成文本。真要出问题至少知道自己装过什么重装实例时心里有数。2.2 把后悔药先备好模拟器普遍自带备份功能。以带命令行工具的版本为例可以用类似backup的子命令把整个实例打包成单个备份文件比如备份到 D 盘# 关闭实例后再备份具体可执行文件名以安装目录为准 ldconsole.exe backup --name 实例名 --file D:\bak\instance_2024.ldbk没有命令行工具也没关系模拟器界面上一般都有备份/还原或者导出应用的入口。我的习惯是分两层备份第一层用模拟器自带的整体备份第二层把重要应用的数据用adb backup单独导一份。虽然adb backup在新版本安卓上限制越来越多但对模拟器这种 root 环境通常还是可用的。# 导出单个应用的私有数据注意这只是补充手段 adb backup -f wx.ab -noapk com.tencent.mm还有一个更省事的退路如果这个实例本来就是个随手测试用的环境里面没有不能丢的东西那最干脆的方案是——直接在模拟器里把重要文件导出到宿主机然后删掉整个实例重建一个。新建实例的 data 分区小而干净比花两小时抠空间划算得多。2.3 操作前必须把进程停干净这一步看似废话但我见过太多人卡在这儿。虚拟磁盘文件在模拟器运行时是被独占锁定的你直接删、直接压缩要么报文件正在使用要么压缩工具假装成功实际什么都没干最坏的情况是磁盘文件被写坏实例直接报废。正确顺序是先在模拟器界面里正常关闭实例然后确认托盘图标消失最后打开任务管理器检查有没有残留的模拟器主进程、后台服务进程、adb 服务进程全部结束掉。有些模拟器还带一个常驻的多开辅助进程它也会持有文件句柄容易漏掉。保险起见可以等三十秒再做下一步操作。另外操作前把宿主机上正在跑的杀毒软件实时防护临时关一下大文件读写被实时扫描拖慢几十倍是常事我上次压缩一个 40GB 的盘开着防护跑了四十分钟关掉之后七分钟搞定。3. 释放 data 分区空间的五层手段从轻到重逐级上3.1 第一层模拟器自带清理与存储设置先别急着动命令行把模拟器自带的工具用足。绝大多数模拟器在设置里有存储或者磁盘清理入口能直接看到 data 分区的占用构成并按类别给出可清理项比如应用缓存、安装包残留、日志文件、无用的临时文件。这层操作零风险可以当日常维护。安卓系统内部本身也有清理入口。进设置里的存储界面能看到应用和缓存两块。点进应用列表按大小排序把那些认识且不需要的应用直接卸载。安卓自带的文件应用或者第三方文件管理器可以扫出重复文件、大文件、空文件夹。还有两个地方经常被忽略。一是下载目录模拟器下载的安装包从来不删一个游戏包动辄两三个 G攒一年能攒出一整块盘。二是Android/data目录很多应用把离线资源包塞在这里卸载应用时它留下的目录经常不会被清掉这些残留包名目录就是纯垃圾。实测下来这一层能解决大概三到四成的问题。但如果你面对的是一个跑了很久的重度实例光靠界面点击是清不完的因为很多垃圾藏在/data/data深处界面上根本看不到。3.2 第二层ADB 精确定位与定点清理到这一步就得上命令行了。绝大部分模拟器都开放 ADB 调试连接方式有两种一种是模拟器自动把 adb 服务挂上去直接在宿主机终端里敲adb devices就能看到设备另一种需要你手动adb connect 127.0.0.1:5555这类端口。端口号在模拟器设置里查多开实例会依次递增。连上之后先看整体分区情况adb shell df -h输出里找到挂载点是/data的那一行看容量和已用。接着往下钻找出到底是谁在占地方。下面的命令按目录体积倒序排列只列前二十个adb shell du -sh /data/* 2/dev/null | sort -hr | head -20 adb shell du -sh /data/data/* 2/dev/null | sort -hr | head -20 adb shell du -sh /data/media/0/* 2/dev/null | sort -hr | head -20/data/data这一层需要 root 权限才能读全。模拟器通常自带 root可以在设置里打开或者在终端执行adb root提权。提权成功后adb shell进去就是#提示符。定位到具体包名之后优先用系统命令清理而不是直接rm因为pm clear会同时清掉数据库和缓存目录比手删更干净# 清空某个应用的私有数据保留应用本体 adb shell pm clear com.example.app # 给当前用户卸载预装应用不删系统镜像里的 APK adb shell pm uninstall -k --user 0 com.example.bloat然后是那些固定的垃圾堆逐个清掉adb shell rm -rf /data/local/tmp/* adb shell rm -rf /data/log/* adb shell rm -rf /data/anr/* adb shell rm -rf /data/tombstones/* adb shell rm -rf /data/system/dropbox/* adb shell rm -rf /data/cache/* adb shell rm -rf /data/media/0/Android/data/*/cache/* adb shell sync最后那个sync别省略它把内存里的写入刷回磁盘避免你强制关进程时数据写丢。清完再用df -h看一眼通常能看出明确的下降。提示/data/media/0/Android/data/*/cache这个通配符在部分精简过的 shell 里不生效如果报错就先用ls列出目录名再逐个删或者进adb shell交互模式里执行。3.3 第三层清快照、清冗余实例模拟器的快照机制是空间的隐形杀手。你每按一次保存状态就是给整个实例拍一张全量或增量快照快照文件动辄几个 G。更麻烦的是很多人不知道自己存过快照因为界面上的入口比较隐蔽。实例目录里如果存在类似Snapshots、snapshot这样的文件夹或者一堆带时间戳的磁盘文件那就是快照的痕迹。处理方式分两种如果模拟器界面提供了快照管理直接在界面里删如果没有就在完全关闭模拟器之后把快照文件夹整体删掉。删之前确认你不需要回滚到那个状态。另一个常被忽略的是冗余实例。多开玩家手里往往堆着七八个实例其中一半是当初测某个东西临时建的之后从来没开过。这些僵尸实例每个都要占几个 G 起步加起来非常可观。我的做法是定期清理打开模拟器自带的多开管理界面看每个实例最后使用时间超过三个月没碰的先导出里面可能有用的小文件然后整个删除。还有一个细节删除实例不一定等于删除磁盘文件。有些模拟器的删除只是从列表里摘掉文件夹还在原处。删完之后一定要去vms目录里核对把残留文件夹手动清掉不然空间根本没回来。3.4 第四层零填充加磁盘压缩让宿主机真正回收前三层做完模拟器内部的空间是清出来了但宿主机上那个虚拟磁盘文件大概率还是原来的大小。这一层就是解决这个问题的核心手段。原理不复杂虚拟磁盘里被删掉的数据块宿主机并不知道它们是空闲的因为磁盘上的内容还是旧数据的残影。我们要做的是往安卓系统里写一个巨大的全零文件把剩余空闲空间填满这样空闲块的内容就从旧数据残影变成了全零。全零块是高度可压缩的接下来用磁盘工具做收缩宿主机就能把这些块真正释放掉过程有点像给气球放完气再叠起来。第一步在安卓系统内做零填充。先确认剩余空间足够写点东西adb shell df -h /data然后在adb shell里执行注意这会临时占满剩余空间写好之后立刻删掉dd if/dev/zero of/data/zerofill.bin bs4M rm -f /data/zerofill.bin syncdd写到空间不足时会报错退出这是正常的不用管。关键是要让它尽量写满。如果模拟器的/data空间特别大这个过程可能要几十分钟耐心等。写完之后立刻删除重启一次模拟器让系统重新整理空闲块。第二步用磁盘工具做收缩。这一步风险最高务必先复制一份虚拟磁盘文件做备份。如果模拟器底层用的是常见的虚拟磁盘格式可以用对应的官方磁盘管理工具做收缩操作时严格指向你要处理的那个磁盘文件千万别指错路径。注意如果盘面上原本就有一个SHRINK或COMPACT的开关优先用模拟器自带的磁盘压缩功能它比第三方工具更了解自己的镜像结构。第三方工具压缩失败时可能只破坏了镜像头表面看文件变小了实际一启动就报错这种损伤是不可逆的。第三步验证。重新启动实例看能不能正常进系统用df确认 data 分区容量没变、数据还在再回宿主机看文件占用空间是否下降。我实测过一次一个 46GB 的data.vmdk压缩后占用降到 13GB释放了三十多个 G效果非常明显。3.5 第五层数据目录迁移与实例重建如果第四层你觉得风险太大或者压缩工具在你的镜像上就是跑不通还有个更朴素但绝对安全的方案把整个模拟器数据目录搬到别的盘用目录联接junction把路径接回去。具体操作顺序很关键我把它拆开写# 1. 完全关闭模拟器确认没有残留进程 # 2. 在目标盘建好目录比如 D:\EmuData # 3. 把原 vms 目录改名留作后备 ren C:\模拟器安装目录\vms vms_old # 4. 创建目录联接注意 /J 是目录联接不需要管理员权限 mklink /J C:\模拟器安装目录\vms D:\EmuData\vms # 5. 把 vms_old 里的内容剪切到 D:\EmuData\vms # 6. 启动模拟器验证一切正常后再删除 vms_old这个方案的好处是宿主机 C 盘立刻松一口气模拟器照常用data分区的逻辑容量一点没变。代价是如果你的 D 盘是机械硬盘模拟器启动和读写会明显变慢所以尽量挑一块 SSD 做目标盘。如果连迁移都嫌麻烦那就直接重建。把实例里需要的东西导出——照片视频拷出来、重要应用数据备份一下、聊天记录尽量用应用自带的迁移功能转出去——然后删掉整个实例重新建一个。新建实例的data分区干净得像刚出厂的手机而且你可以趁这个机会在创建时就规划好磁盘容量别一上来就给 64GB用多少给多少后面需要再扩。我现在的习惯是测试用途的实例给 16GB重度用途给 32GB够用就行。4. 常见问题与排查技巧实录4.1 删完文件宿主机上空间一点没回来这是最高频的问题也是本文开头那个朋友的处境。原因就是前面讲的稀疏磁盘机制——你在 guest 里删除host 端不知情。判断方法很简单打开 WizTree 或者 TreeSize 这类工具用管理员权限扫描模拟器目录看虚拟磁盘的占用空间和大小差多少。如果差得很多说明有大量空闲块没被回收走第四层的零填充加压缩流程。还有一个变种情况删完之后空间确实回来了一点但过一天又涨回去了。这通常是因为某个应用在后台重新下载了资源或者系统的日志服务重新写满了。排查方法是清理完立刻记一次空间隔两小时再记一次对比增长量然后针对那个时间段内写盘最多的目录下手。4.2 清理之后开不了机、黑屏、卡进度条这种情况我遇到过两次两次原因不一样。第一次是删了/data/dalvik-cache之后低配机器上首次启动重新编译所有应用卡在开机动画上十几分钟。这不是故障是正常现象耐心等就行。第二次是把/data/misc一起端了结果系统起不来因为证书存储和网络配置都在这儿最后只能重装实例。排查套路是这样的先看模拟器有没有提供安全模式或者恢复模式入口能进系统的话第一时间把/data/system/dropbox里的异常报告拉出来看里面会写清楚哪个组件起不来。如果连系统都进不去就用提前做好的备份整体还原。这也再次说明为什么第 2 章要强调备份。另外补充一句如果开机卡在 99% 或者某个固定百分比不动先排除宿主机的问题虚拟化支持有没有被别的软件占用、内存分配是不是太小、磁盘所在分区是不是已经满了。这些跟 data 分区清理无关但表现出来很像。4.3 顺带说说那个剪贴板被占用的报错搜索这个话题的时候经常能看到无法释放剪贴板上的空间、另一程序可能正在使用剪贴板这类报错跟模拟器混在一起。这里要分清楚这类提示绝大多数不是模拟器产生的而是宿主系统层面剪贴板被别的程序持有导致的尤其是处理大段文本表格的时候特别容易触发。它的典型特征是弹窗出现后复制粘贴功能直接失效重启那个持有剪贴板的程序或者注销一次会话就好了跟模拟器磁盘空间没有任何关系。模拟器场景下唯一沾边的是跨设备共享剪贴板功能。当你在模拟器和宿主机之间来回粘大段文本时共享通道偶尔会卡住。解决办法很简单在模拟器设置里把共享剪贴板关掉再打开一次或者重启模拟器的后台服务进程。这个功能对日常使用挺方便但如果你不做跨端复制关掉能省一点资源和麻烦。4.4 常见问题速查表现象最可能的原因处理方向模拟器内已清理宿主机空间不变稀疏磁盘空闲块未回收零填充后做磁盘压缩清理后空间短暂下降又涨回后台应用重新下载资源、日志重写按时间段定位高频写入目录开机卡在动画或进度条dalvik-cache 重建、系统组件被误删耐心等待或还原备份压缩时报文件被占用模拟器或后台服务进程未完全退出结束所有相关进程后再操作删除实例后空间没回来只是从列表移除文件夹仍在手动清理vms下残留目录复制粘贴突然失效宿主机剪贴板被其他程序占用重启持有程序或重新登录会话迁移目录后启动报错联接创建顺序有误、权限不足按第 3.5 节顺序重做一遍5. 让 data 分区不再暴涨的长期习惯5.1 使用习惯上的三个动作清理是治标控制增长才是治本。我自己坚持的三个习惯效果比年度大扫除好得多。第一个是给实例做用途隔离。刷视频、玩游戏、跑测试这三类需求分开建实例互不干扰。好处是每个实例的 data 分区规模可控哪个涨得厉害一眼就能看出来也方便单独处理。把所有东西堆在一个实例里最后就是什么都舍不得删。第二个是定期看一次目录体积排行。不用天天看一个月扫一次就够。命令就那两条两分钟的事但能让你在空间失控之前就发现问题。看到某个陌生包名占了好几个 G顺手一查往往是某个早就卸载的应用留下的残留。第三个是把模拟器数据目录放在非系统盘。C 盘留给系统和常用软件模拟器的数据目录用第 3.5 节的联接方案挪到别的 SSD 上。这样即使某个实例失控膨胀也不会拖垮整个系统最多是那块盘紧张。5.2 多开场景下的空间规划多开玩家的情况更复杂因为你是按倍数在消耗空间。十个实例每个 20GB就是 200GB一块 512GB 的盘瞬间过半。我的规划思路是按基础镜像 差异来理解。多个实例如果是从同一个副本克隆出来的它们的系统盘内容高度相似真正有差异的是 data 分区。所以能共享的尽量共享能做小做小。具体几个动作新建实例时磁盘容量按需给别贪大克隆实例之后立刻进系统把克隆过来的垃圾数据清掉别带着前一个实例的历史包袱跑长期不用的实例导出备份后整个删除需要时再还原。还有一点别在一个盘上开太多实例同时跑。除了空间I/O 也是瓶颈几个实例同时读写会互相拖慢最后每个都卡。我一般控制在同盘同时运行不超过三个。5.3 网络设备类模拟器的空间逻辑对比顺便说一句很多人搜模拟器占用空间的时候其实找的是另一类工具——网络设备模拟器。这类工具的占用逻辑跟安卓模拟器完全不是一回事。它们主要吃两块空间一是安装目录里的系统镜像文件一个镜像动辄几个 G二是每台虚拟设备的配置文件、抓包记录、日志。所以清理思路也不一样重点在镜像文件管理和日志清理没有 data 分区这个概念。至于设备起不来这类问题通常跟虚拟化平台冲突、镜像版本不匹配有关跟磁盘空间的关系反而没那么大。把这两类工具分开理解排查时能少走很多弯路。6. 几个我踩过之后才明白的细节最后说几个只有真动过手才会知道的点都是我自己付过代价换来的。第一个别在模拟器运行中做任何磁盘层面的操作。压缩也好、迁移也好、删文件也好一定要完全停干净。我最早图省事直接对着运行中的虚拟磁盘文件动手压缩工具跑了一半报错退出结果那个镜像的头结构坏了实例直接报废里面的东西也捞不出来。第二个备份要趁早而且要验证。备份文件生成出来不代表能用我建议生成之后立刻在另一个位置还原一次试试确认能正常启动。我吃过一次亏备份文件生成了但做的是增量备份源实例删掉之后增量根本没法单独还原。第三个零填充别在空间紧张的机器上做。这个操作会临时把剩余空间填满如果你的盘本来就快满了写的过程中可能触发别的程序报错。而且填满再删的过程对磁盘有一定写入压力SSD 上还好机械盘上会很慢要有心理准备。第四个NTFS 的文件压缩不要用在虚拟磁盘上。右键属性里那个压缩内容以节省磁盘空间看着很诱人但虚拟磁盘本身是高频率随机读写的挂上 NTFS 压缩之后每次读写都要解压压缩性能掉得厉害而且和模拟器自己的磁盘机制可能冲突。想省空间老老实实走零填充加压缩的流程。第五个也是最重要的一条如果你手上这个实例已经折腾了很久各种残留盘根错节那最省时间的选择就是导出数据、推倒重建。清理这件事边际收益下降得非常快有时候花三小时抠出五个 G还不如备份加重建来得痛快。判断标准很简单——如果清理花的时间超过重建加重新配置的时间那就别犹豫了。我用这套流程处理过从 8GB 到 58GB 不等的各种实例绝大多数情况走完前三层就能有明显改善第四层用来让宿主机真正回血第五层是兜底方案。你按这个顺序往下走基本不会出大问题。唯一需要反复提醒的还是那句动手之前先备份动手之前先备份。