Java中隐藏的性能优化之Integer缓存揭秘

本文详细解析了Java中Integer类的缓存机制,尤其是在处理整数时的自动装箱和拆箱过程。通过IntegerCache,它优化了-128到127范围内的整数,减少内存消耗。
摘要由CSDN通过智能技术生成

开篇

在Java中,我们经常使用Integer类来处理整数。但是,你可能不知道,Integer类有一个隐藏的性能优化机制,那就是缓存。是的,你没有听错,Integer类确实有缓存机制。这个机制是如何工作的,又是如何在我们日常编程中发挥作用的呢?本文将为你揭开这个神秘的面纱。

代码示例

首先,让我们审视以下的代码示例,并尝试预测其结果。看看是否能够准确猜测它的输出。

示例一:

public static void main(String[] args) {
    int n1 = 100;
    int n2 = 100;
    int n3 = 1000;
    int n4 = 1000;
    System.out.println(n1 == n2);
    System.out.println(n3 == n4);
}
运行结果:true true

ok,我相信大家这个是没有问题的。因为基本类型通过==运算符比较的是它们数值的大小。

示例二:

public static void main(String[] args) {
    Integer n1 = 100;
    Integer n2 = 100;
    Integer n3 = 1000;
    Integer n4 = 1000;
    System.out.println(n1 == n2);
    System.out.println(n3 == n4);
}
运行结果:true false

真的吗?n3 == n4的比较结果竟然不是true。我们现在感到有些困惑了。

示例三:

public static void main(String[] args) {
     int n1 = 1000;
     Integer n2 = 1000;
     System.out.println(n1 == n2);
 }
 运行结果:true

怎么这个结果又变成了true了呢?

原理分析

为了搞清楚问题的根源,我们分析一下它们的字节码。首先,我们看一下示例二的字节码,如下图:
示例二代码的字节码
在字节码层面,我们可以观察到,为Integer类型的变量赋予一个int类型的值时,会触发对Integer类的valueOf静态方法的调用,把int类型转换成Integer类型,这个过程就是我们所说的自动装箱。接下来我们继续分析一下valueOf这个静态方法。

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

从上述方法中,我们发现又涉及到了一个静态内部类IntgerCache。

private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[];

    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            try {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            } catch( NumberFormatException nfe) {
                // If the property cannot be parsed into an int, ignore it.
            }
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);

        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }

    private IntegerCache() {}
}

从上述代码中,我们可以了解到Java中Integer类的缓存机制是通过一个精心设计的静态内部类IntegerCache来实现的。这个机制虽然简单,但却非常高效,它利用了一个静态数组来缓存特定范围内的数值,默认范围为[-128, 127]。

此时,我们再来看一下Integer.valueOf()方法的代码,不难得出这样一个结论:当我们调用valueOf()方法时,如果传入的整数值在-128到127之间,方法会直接返回缓存中的对象,而不是创建一个新的对象。现在大家应该已经明白了为什么示例二的运行结果是如此了吧。

最后,我们再看一下示例三的字节码,如下图:
示例三的字节码
在上述的字节码中,我们可以发现,当Integer类型的变量与一个int类型的变量使用==运算符比较时,会触发对Integer.intValue方法的调用,把Integer类型转换成int类型,这个过程就是我们所说的自动拆箱。

总结

Integer缓存机制是Java 5中引入的一项优化措施,它针对自动装箱过程中整数值的频繁使用进行了优化。这种机制特别适用于-128到127之间的整数值,因为这个范围内的整数值在实际应用中使用最为频繁。通过缓存这些常用的整数值,可以避免在自动装箱时频繁地创建和销毁对象,从而减少了内存的消耗。

  • 13
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丿微风乍起

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值