2017-05-15 39 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实例被创建。

相关问题