1 基本概念
2 命令解讀
2.1 adb shell df
df 命令主要用于需要檢查文件系統上已使用和可用的磁盤空間的數量。如果沒有指定文件名,則顯示在當前所有掛載的文件系統上可用的空間。其原理是從proc/mounts 或 /etc/mtab 中檢索磁盤信息。
注意:df命令并不是來打印當前磁盤各個文件的大小,而是打印當前掛載的文件系統和塊設備之間的關系。
df命令平時使用的多的參數是df -h和df -a。
df -a能夠打印當前所有文件系統,包括偽的(具有0塊的偽文件系統(沒有直接綁定到物理設備))、重復的、不可訪問的文件系統。
df -h是以人類可讀的方式打印,它還會自動過濾到那些沒有占空間的文件系統,例如:
C:\Users\pengcheng.ding>adb shell df -h
Filesystem Size Used Avail Use% Mounted on
/dev/block/dm-5 692M 690M 2.0M 100% /
tmpfs 911M 3.1M 908M 1% /dev
tmpfs 911M 0 911M 0% /mnt
/dev/block/dm-6 337M 336M 1.0M 100% /system_ext
/dev/block/dm-7 215M 214M 684K 100% /vendor
/dev/block/dm-8 122M 121M 392K 100% /product
tmpfs 911M 16K 911M 1% /apex
tmpfs 911M 764K 910M 1% /linkerconfig
/dev/block/mmcblk0p7 16M 116K 16M 1% /metadata
/dev/block/mmcblk0p9 2.9M 84K 2.9M 3% /mnt/vendor/protect_f
/dev/block/mmcblk0p10 5.4M 76K 5.4M 2% /mnt/vendor/protect_s
/dev/block/mmcblk0p6 52M 1.6M 50M 4% /mnt/vendor/nvdata
/dev/block/mmcblk0p5 24M 32K 24M 1% /mnt/vendor/nvcfg
/dev/block/mmcblk0p12 38M 52K 38M 1% /mnt/vendor/persist
/dev/block/dm-43 24G 23G 1.0G 96% /data
/dev/block/loop8 22M 22M 28K 100% /apex/com.android.extservices@340090000
/dev/block/loop5 232K 104K 128K 45% /apex/com.android.scheduling@340090000
tmpfs 911M 0 911M 0% /data_mirror
/dev/block/loop7 7.6M 7.6M 28K 100% /apex/com.android.wifi@340090000
/dev/block/loop10 24M 24M 32K 100% /apex/com.android.art@340090000
/dev/block/loop9 3.1M 3.0M 32K 99% /apex/com.android.neuralnetworks@340090000
/dev/block/loop6 232K 196K 36K 85% /apex/com.android.configinfrastructure@340090000
/dev/block/loop13 4.2M 4.2M 32K 100% /apex/com.android.media@340090000
/dev/block/loop12 12M 12M 28K 100% /apex/com.android.vndk.v34@1
/dev/block/loop11 764K 736K 28K 97% /apex/com.android.tzdata@340090000
/dev/block/loop14 14M 14M 32K 100% /apex/com.android.permission@340090000
/dev/block/loop17 2.0M 2.0M 32K 99% /apex/com.android.os.statsd@340090000
/dev/block/loop18 20M 20M 28K 100% /apex/com.android.media.swcodec@340090000
/dev/block/loop16 2.8M 2.8M 28K 100% /apex/com.android.resolv@340090000
/dev/block/loop15 21M 21M 32K 100% /apex/com.android.btservices@340090000
/dev/block/loop19 18M 18M 40K 100% /apex/com.android.adservices@340090000
/dev/block/loop20 488K 460K 28K 95% /apex/com.android.sdkext@340090000
/dev/block/loop22 33M 33M 28K 100% /apex/com.android.i18n@1
/dev/block/loop24 4.1M 4.0M 32K 100% /apex/com.android.adbd@340090000
/dev/block/loop23 14M 14M 28K 100% /apex/com.android.tethering@340090000
/dev/block/loop21 19M 19M 28K 100% /apex/com.android.vndk.v33@1
/dev/block/loop27 8.0M 8.0M 32K 100% /apex/com.android.mediaprovider@340090000
/dev/block/loop31 3.1M 3.1M 32K 100% /apex/com.android.conscrypt@340090000
/dev/block/loop26 3.3M 3.3M 32K 100% /apex/com.android.runtime@1
/dev/block/loop25 12M 12M 28K 100% /apex/com.android.cellbroadcast@340090000
/dev/block/loop29 5.2M 5.2M 32K 100% /apex/com.android.devicelock@1
/dev/block/loop30 2.7M 2.6M 28K 99% /apex/com.android.appsearch@340090000
/dev/block/loop28 2.8M 2.8M 28K 100% /apex/com.android.uwb@340090000
/dev/block/loop32 712K 684K 28K 97% /apex/com.android.ipsec@340090000
/dev/block/loop36 8.4M 8.4M 28K 100% /apex/com.android.healthfitness@340090000
/dev/block/loop34 2.1M 2.1M 32K 99% /apex/com.android.ondevicepersonalization@340090000
/dev/block/loop35 17M 17M 28K 100% /apex/com.android.vndk.v31@1
/dev/block/loop33 252K 220K 32K 88% /apex/com.android.virt@2
/dev/block/loop38 1.0M 0.9M 28K 98% /apex/com.android.rkpd@1
/dev/block/loop37 45M 45M 32K 100% /apex/com.android.vndk.v30@1
/dev/fuse 24G 23G 1.0G 96% /mnt/installer/0/emulated
字段Filesystem
filesystem字段為當前的文件系統類型,通常有如下幾個類型:
- /dev/block/dm-*:通常表示設備映射(Device Mapper)的塊設備。設備映射是 Linux 內核中的一個功能,用于實現高級磁盤映射和管理功能,例如卷管理、快照等。這些文件系統通常代表實際的磁盤分區或邏輯卷。
- /dev/block/mmcblk0p*:通常表示 MMC 塊設備(如 SD 卡、eMMC 等)的分區。這些文件系統代表了存儲在移動存儲設備上的文件系統。
- /dev/block/loop*:代表回環設備(loop device),用于在文件系統中創建虛擬塊設備,可以將文件系統映射為塊設備進行訪問。
- tmpfs:基于內存的臨時文件系統,數據存儲在內存中而不是硬盤上。通常用于存儲臨時數據和文件系統操作。
- /dev/fuse:它是一個特殊的設備文件,用于實現用戶空間文件系統(Filesystem in Userspace,FUSE)的功能。FUSE 是一個允許非特權用戶創建文件系統的框架,它允許用戶空間的程序通過 FUSE 接口來實現文件系統操作,而無需修改內核。這種機制使得開發者可以在用戶空間實現各種自定義的文件系統,而無需深入了解內核編程。有些地方將 FUSE 文件系統稱為虛擬文件系統,是因為這種文件系統并不是基于硬件設備或真實存儲介質的,而是在用戶空間中通過程序動態創建的。從內核的角度看,FUSE 文件系統并不是一個傳統意義上的文件系統,它是在用戶空間中模擬文件系統接口的一種機制。
字段Mounted on
Mounted on字段顯示了文件系統掛載的目標路徑。
/dev/block/dm-7塊設備總大小215M,已經使用214M,掛載在/vendor目錄
/dev/block/dm-7 ? ? ? 215M 214M ?684K 100% /vendor?
/apex目錄是一個基于內存的臨時數據,占用了16K的大小
tmpfs ? ? ? ? ? ? ? ? 911M ?16K ?911M ? 1% /apex
下面這種看起來是mainline里面的應用,被作為回環設備進行掛載
/dev/block/loop12 ? ? ?12M ?12M ? 28K 100% /apex/com.android.vndk.v34@1
/dev/block/dm-43塊設備總大小24G,已經使用23G,掛載在/data目錄
/dev/block/dm-43 ? ? ? 24G ?23G ?1.0G ?96% /data? ?
/dev/fuse作為虛擬文件系統被掛載在/mnt.installer/0/emulated
/dev/fuse ? ? ? ? ? ? ?24G ?23G ?1.0G ?96% /mnt/installer/0/emulated?
為什么/dev/fuse和/data使用情況基本保持一致?
2.2 adb shell du
du命令主要用于需要了解系統上的目錄或文件所使用的磁盤空間量。當試圖識別占用大部分磁盤空間的大文件或目錄時,它特別方便。
du命令可以直接遍歷當前目錄各個子文件或者子文件夾大小,用起來很方便。
其中du --max-depth=1 指定深度為1
2.3 dumpsys?devicestoragemonitor
參考Android 系統服務之DeviceStorageMonitorService-CSDN博客
3 Android相關機制
3.1?DeviceStorageMonitorService
DeviceStorageMonitorService是framework中實時檢查當前設備是否存在底存儲空間狀態的服務,他繼承于systemserver。?參考Android 系統服務之DeviceStorageMonitorService-CSDN博客
我們可以通過dumpsys?devicestoragemonitor來獲取他的一些信息。
C:\Users\pengcheng.ding>adb shell dumpsys devicestoragemonitor
Known volumes:Default:level=LOW lastUsableBytes=476016640lowBytes=524288000 fullBytes=1048576path=/datamSeq=1 mForceState=UNKNOWN
這里我們接著來討論一下df命令里面為什么/dev/fuse和/data使用情況基本保持一致?因此我做了如下幾個實驗:
步驟一:填充/sdcard/Movies,/dev/block/dm-43和/dev/fuse的可用空間為557M
步驟二:確認當前是否處于低存儲狀態,確認當前還未達到LOW狀態
步驟三:adb push 150M文件到/sdcard/Movies目錄,確認狀態
填充到/sdcard/Movies目錄會占用/data目錄空間,即/data剩余可用減少了151M從而導致設備進入LOW狀態。
此時緊接著繼續推送一個55M的文件,能夠繼續推送成功,即lowBytes并不會阻礙文件存儲,但是install應用的地方會去檢驗這個值。
步驟四:adb push 150M文件到/data目錄,確認狀態
總結:通過步驟3和步驟4可以看出來/data和/sdcard/目錄基本完全一致,他們的設備存儲介質是一致的?
3.2 /sdcard目錄到是怎么回事?
進入根目錄,執行ls -la命令:
D50:/ # ls -la
drwxrwx--x 62 system system 4096 2025-02-24 22:08 data
lrw-r--r-- 1 root root 21 2009-01-01 08:00 sdcard -> /storage/self/primary
進入/storage/self/primary的父目錄,執行ls -la命令:
D50:/storage/self # ls -la
lrwxrwxrwx 1 root root 19 2025-02-24 20:00 primary -> /storage/emulated/0
因此我們可以發現/mnt/installer/0/emulated和/storage/emulated基本一致,那么為什么他們是一致的呢?中途也沒有發現任何軟鏈接引用的地方?
那么這兩個目錄和/data目錄有什么關聯呢?也沒有發現任何軟鏈接引用的地方?
因此/mnt/installer/0/emulated和/storage/emulated和/data/media居然指向同樣的地方?
- reboot設備在開機logo階段,執行df -h此時還沒有/dev/fuse節點的文件系統,因此此時系統上層還未創建虛擬文件系統,因此針對linux內核來說它就是一個虛擬的。
- 完全開機之后,執行df -h出現了/dev/fuse,但是掛載的路徑卻變成了/storage/emulated,如下截圖,因此這個掛載點可能還是隨機的,但都是同一個物理塊