1. 程式人生 > >用ls和du顯示的檔案大小為何有差別

用ls和du顯示的檔案大小為何有差別

du == disk usage (磁碟使用量,佔用的磁碟空間)
ls == apparent sizes(檔案長度,file資料結構中定義的檔案長度欄位)
    一個檔案佔用的磁碟空間和一個檔案的大小是兩碼事情。佔用空間取決於檔案系統的塊(block)的大小,Linux一般預設是4k(4096) ,因此,一個大小為1個位元組的檔案,最小也要佔用4k,如果你建立檔案系統的時候制定塊大小是16K,那麼即便一個檔案只有1個位元組,佔用空間也是16K。
   通常情況下,ls 顯示的檔案大小比du顯示的磁碟佔用空間小,比如檔案系統的block是4K,一個13K的檔案佔用的空間是 13k/4k = 3.25 個block,一個block只能被一個檔案佔用,因此實際佔用空間就是4個block,就是16K。

     經常發現rm刪除某個檔案後,儲存並沒有被釋放

     rm日誌檔案,但日誌檔案一直被服務A的程序打開了, rm 後空間並沒有釋放。rm 其實是刪除該檔名到檔案真正儲存到磁碟位置的連結, 此時該檔案控制代碼還被服務A開啟, 因此對應的資料並沒有被回收, 其實可以理解為 GC 裡面的引用計數, rm 只是減少了引用計數, 並沒有真正的進行釋放記憶體, 當引用計數為0的時候, OS 核心才會釋放空間, 供其他程序使用。所以當A程序停止(檔案控制代碼的引用計數會變為0)或者重啟後, 佔用的儲存空間才被釋放。 (lsof | grep deleted:查詢所有被刪除的但是檔案控制代碼沒有釋放的檔案和相應的程序,然後再kill掉程序或者重啟程序即可)。


  該日誌檔案是一個稀疏檔案,雖然其檔案長度很大, 然而其中包含大量的holes並不佔用實際的儲存空間.


以上是用 dd 等命令建立稀疏檔案, 也有同學用 c 程式碼實現了相同的功能. 其實就是寫檔案的時候, 改變下當前檔案寫指標。


If the environment variable BLOCKSIZE is set, and the -k option is not specified, the block counts will be displayed in units of that size block. If BLOCKSIZE is not set, and the -k option is not specified, the block counts will be displayed in 512-byte blocks.

although the apparent size is usually smaller, it may be larger due to holes in (‘sparse’) files, internal fragmentation, indirect blocks, and the like (man du)

Display values are in units of the first available SIZE from –block-size, and the DU_BLOCK_SIZE, BLOCK_SIZE and BLOCKSIZE environment variables. Otherwise, units default to 1024 bytes (or 512 if POSIXLY_CORRECT is set. (du --help)

   可以用修改檔案內容的方式在不用重啟程序的情況下釋放空間,用echo 'hello' > contentutil.log, 然後 df 確認磁碟空間確實已經釋放。

參考:http://mp.weixin.qq.com/s?__biz=MzAxODI5ODMwOA==&mid=2666540078&idx=2&sn=cacb3bcb3bd9a06cc8cfca16e02bfbd9&chksm=80dce885b7ab619359cb73732a1505b440861af707a2abceed1de5d6496e96e82e1b76dce330&mpshare=1&scene=1&srcid=12061rCRjhAoxF9ctqTcUWEb#rd