2

我有使用共享內存的多進程應用程序。我試圖在我的應用程序中檢測內存泄漏。我在/ proc/$ PID/SMAP共享內存中的Shared_dirty vs Private_dirty

2b51cd2b2000-2b53b8aa4000 rw-s 00000000 00:09 17151225     /dev/zero (deleted) 
    Size:   8052680 kB 
    Rss:    31608 kB 
    Shared_Clean:  1524 kB 
    Shared_Dirty:  25736 kB 
    Private_Clean:  0 kB 
    Private_Dirty:  4348 kB 
    Swap:     0 kB 
    Pss:    6945 kB 

這是我分配的共享內存中找到這個。(尺寸告訴這是一個這是由我的mmap分配)

我試圖理解在這種情況下Shared/Private之間的區別,內存本身是共享的。看到''的標誌。

如果任何人可以解釋Shared_Clean與Private_Clean Shared_Dirty與Private_Dirty之間在共享內存上的區別。

回答

5

Clean和Dirty之間的區別是指頁面在寫入內存後是否已寫入後備存儲區。對於/dev/zero的映射,頁面明顯是從未書寫,所以只有讀過乾淨頁面而已寫入髒頁面。

對於共享映射,Private和Shared的區別在於頁面是否只被您正在檢查的進程引用,或者它們是否被多個進程引用。

因此,在總結:

  • Shared_Clean是已經通過這個過程引用映射中的頁面和至少一個其他的過程,而不是由任何進程寫的;
  • Shared_Dirty是映射中由該進程和至少一個其他進程引用並由至少一個進程寫入的頁面;
  • Private_Clean是映射中已被讀取但不被此進程寫入但未被任何其他進程引用的頁面;
  • Private_Dirty是映射中已由此進程寫入但未被任何其他進程引用的頁面。

當頁面被寫入時,頁面可以從「乾淨」轉移到「髒」,而當另一個進程引用它時,頁面可以從「私有」轉移到「共享」。

如果映射一個真實的磁盤文件,那麼頁面在內核寫出時也可以從Dirty移動到Clean。

+0

Private_Dirty是否必然意味着進程正在使用mmap,或者有沒有其他更直接的方法可以將進程寫入映射中的頁面? – Masseman

+0

@Masseman:當然不是,堆棧也是一個映射,其本質往往完全是'Private_Dirty'。 – caf