HashMap的jol足迹<integer,integer =“”>

时间:2017-05-15 08:49:41

标签: java hashmap footprint jol

我对物体足迹的理解存在问题:

我在两种情况下运行以下行 A B

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());

案例结果是:

java.util.HashMap@1f89ab83d 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的结果是:

java.util.HashMap@1f89ab83d 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之间的差异是128个Integer实例(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]

1 个答案:

答案 0 :(得分: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实例。