首頁  >  問答  >  主體

android - java中使用MAT是shallow size 单位是什么

java中shallow size 单位是什么

伊谢尔伦伊谢尔伦2744 天前852

全部回覆(1)我來回復

  • 天蓬老师

    天蓬老师2017-04-18 10:51:59

    想說清楚shallow size就必須提到Retained Size。
    shallow size: 表示自身物件所佔用的大小。
    retained size: 自身物件+引用物件的retained大小。

    先借用一張圖,這張圖更能清楚的表示他們之間的計算關係。

    B的shallow size = B;

    B的retained size = B shallow size + C retained size + D retained size;

    在舉例之前,首先要了解JAVA物件在堆中的存儲,我們以32位元JVM虛擬機為例:
    JAVA物件在堆中共有3個部分組成:

    1. 物件頭
      物件頭又包含兩部分資料;
      一:運行時資料。 32位元JVM為32位元即4byte.64位元為8byte.
      二:型別指標。

    2. 實例資料
      即存放實例變數的數據,變數型別包括兩種 基本型別變數和參考變數。
      基本型別變數所佔據的位元組大小就不說了,引用變數我們存放的是指標。

    3. 填充資料
      物件儲存空間為8byte的整數倍,如果物件頭+實例資料不足8byte的整數倍,則進行填充。

    說到引用型別大小,32位元虛擬機器下引用佔據4byte. 64位元虛擬機器下方如果不開啟指標壓縮,則引用佔據8byte。

    下面我們根據例子進行說明:

    public class TestObjSize {
        private int a = 1;
        private boolean b = true;
        private TestObjSize testObjSize;
        
        public static void main(String[] args) {
            Object object = new Object();
            TestObjSize test = new TestObjSize();//这个new出来的对象记为obj1
            test.testObjSize = new TestObjSize();//这个new出来的对象记为obj2
            
            System.out.println(object.hashCode());
            System.out.println(test.hashCode());
            
            try {
                Thread.sleep(3000000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    因為shallow size與實例變數是否有引用無關,所我們先分析下**TestObjSize的shallow size,
    shallow size = 4byte(對象頭) + 4byte(類型指標) + 4byte(int a) + 1byte(boolean b ) + 4byte(TestObjSize引用) = 17;**
    17不是8的整數倍所以會有7個byte的填充數據,最終TestObjSize類型的實例對象的shallow size = 24;

    根據範例我們看到obj2物件的testObjSize = null,
    obj2的retained size = obj2的shallow size = 24;
    obj1物件的testObjSize為obj2,所以obj1的retained sizeobj1物件的testObjSize是obj2,所以obj1的retained sizeobj1物件的testObjSize為obj2,所以obj1的retained sizeobjize 1的48;

    最後附上heapdump!

    如有錯誤,請看客指證。

    回覆
    0
  • 取消回覆