2017-05-15 66 views
2

的學習判斷足跡我有個問題與對象足跡理解:HashMap中<整數,整數>

我運行下面的行在兩種情況下

out.println(VM.current().details()); 
HashMap<Integer, Integer> hashMap = new HashMap<>(); 
A: 
    for (int i = 0; i < 1000; i++) { 
     hashMap.put(i, i); 
    } 
B: 
    for (int i = 0; i < 1000; i++) { 
     hashMap.put(1000 + i, i); 
    } 

PrintWriter pw = new PrintWriter(out); 
pw.println(GraphLayout.parseInstance(hashMap).toFootprint()); 

案例結果是:

[email protected] footprint: 
COUNT  AVG  SUM DESCRIPTION 
    1  8208  8208 [Ljava.util.HashMap$Node; 
    1872  16  29952 java.lang.Integer 
    1  48  48 java.util.HashMap 
    1000  32  32000 java.util.HashMap$Node 
    2874    70208 (total) 

情況B的結果是:

[email protected] footprint: 
COUNT  AVG  SUM DESCRIPTION 
    1  8208  8208 [Ljava.util.HashMap$Node; 
    2000  16  32000 java.lang.Integer 
    1  48  48 java.util.HashMap 
    1000  32  32000 java.util.HashMap$Node 
    3002    72256 (total) 

A和B之間的差異是Integer的128個實例(1872 vs 2000)。第一個假設是一個IntegerCache影響,但它並沒有解釋我腦海中的情況B.

問題:爲什麼這兩個腳印是不同的?

細節:

jol: "org.openjdk.jol:jol-core:0.8" 

# Running 64-bit HotSpot VM. 
# Using compressed oop with 3-bit shift. 
# Using compressed klass with 3-bit shift. 
... 
# Objects are 8 bytes aligned. 
# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] 
# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] 
+0

我沒有看到任何區別。如果你檢查avg的情況是相同的。我錯過了一些東西? –

+0

@gatisahu我會說平均值是內存佔用量_per instance_自然應該是相同的。 – Thomas

回答

1

的Java確實有cache for Integer instances with values between -128 and 127(直接使用自動裝箱或Integer.valueOf(int)時)。因此put(i,i)將使用相同的實例,而put(1000 + i, i)或甚至put(1000 + i, 1000 + i)不會。

put(i,i)將針對值0到127(即128個實例)使用高速緩存並在兩種情況下返回相同的Integer實例。

put(1000 + i,i)將創建一個新的Integer實例的關鍵,但使用的緩存值0到127(即128實例)

put(1000 + i, 1000 + i)將創建鍵和值兩個新Integer情況下,即使他們有相同的數值。因此,如果你這樣做,你應該看到128個額外的Integer實例被創建。

相關問題