关于IntegerCache.cache的介绍

目录

1、int 和 Integer区别

1.1、int 的大小

1.2、Integer大小

1.3、内存大小

2、Integer a=127 与Integer b=127 

2.1、比较

2.1. 使用 == 比较

2.2. 使用 equals() 比较

2.3. 如果换成 128 呢?

2.2、原因

1. 自动装箱机制

2. 缓存机制

2.3、总结

3、存放区域

3.1. JVM 内存区域划分

1.虚拟机栈(Stack)

2.方法区(Metaspace)

3.堆内存(Heap)

3.2、IntegerCache.cache 

1. 静态变量

2. 自动装箱的流程

3.3、关键点总结

4、扩展知识

4.1、缓存目的

4.2、BigInteger


前言

        在处理内存,性能提升,初始化Interger数据类型的时候,合理利用IntegerCache.cache缓存和BigInteger类型来处理超大整数 时的 精度丢失 和 溢出 问题。


1、int 和 Integer区别

如下图所示:

1.1、int 的大小

        int 是 Java 的基本数据类型,固定占用 4 字节(32 位)

  • 范围
    • 最小值:-2^31 = -2,147,483,648
    • 最大值:2^31 - 1 = 2,147,483,647

1.2、Integer大小

    Integer 是 int 的包装类,属于 对象类型,它的大小 不固定,取决于 JVM 实现和运行环境。

之前在介绍java内存对象布局,可参考:Java对象的内存布局及GC回收年龄的研究-CSDN博客

总大小:12(对象头) + 4(int) + 0~4(对齐) = 16 字节(典型值)

示例

Integer a = 100; // 占用约 16 字节(堆内存)

1.3、内存大小

   Integer 是对象,包含 对象头(用于 JVM 管理)、类型指针(指向类元数据)、字段(int value)。

        int 是基本类型,直接存储值,没有额外开销。


    2、Integer a=127 与Integer b=127 

    2.1、比较

    2.1. 使用 == 比较

    Integer a = 127;
    Integer b = 127;
    System.out.println(a == b); // true
    

    2.2. 使用 equals() 比较

    System.out.println(a.equals(b)); // true
    

    2.3. 如果换成 128 呢?

    Integer a = 128;
    Integer b = 128;
    System.out.println(a == b); // false
    System.out.println(a.equals(b)); // true
    

    2.2、原因

    1. 自动装箱机制

            当你写 Integer a = 127;,Java 会自动将基本类型 int 转换为 Integer 对象。这个过程会调用 Integer.valueOf(int i) 方法。

    2. 缓存机制

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
    
    • 默认缓存范围-128 到 127(可以通过 -XX:AutoBoxCacheMax= 修改上限)。
    • 缓存实现IntegerCache.cache 是一个静态数组,在类加载时初始化。

    2.3、总结

    • 127 在缓存范围内a 和 b 都指向 IntegerCache.cache[127],因此 a == b 为 true
    • 128 超出缓存范围a 和 b 会分别创建两个新对象,因此 a == b 为 false

    3、存放区域

    3.1. JVM 内存区域划分

    • a 和 b 是引用变量:存放在 虚拟机栈
    • IntegerCache.cache 是静态数组:存放在 方法区(Metaspace)
    • 堆内存:仅存放超出缓存范围的 Integer 对象。

    1.虚拟机栈(Stack)

    +-------------------+
    | a -> 方法区的 cache[127] |
    | b -> 方法区的 cache[127] |
    +-------------------+
    

    2.方法区(Metaspace)

    +-------------------+
    | IntegerCache.cache[127] (静态数组元素) |
    +-------------------+
    

    3.堆内存(Heap)

    +-------------------+
    | 仅存放超出缓存范围的 Integer 对象(如 128) |
    +-------------------+
    

    3.2、IntegerCache.cache 

    1. 静态变量

    • IntegerCache 是 Integer 类的 静态内部类,其 cache 数组是 静态变量
    • 根据 JVM 规范:
      • 静态变量 存放在 方法区的静态变量区(在 Java 8 及以后,方法区默认使用 Metaspace)。
      • 对象实例 存放在 堆内存

    2. 自动装箱的流程

    Integer a = 127; // 自动调用 Integer.valueOf(127)
    
    • Integer.valueOf(int i) 会检查 i 是否在缓存范围内(-128 ~ 127)。
    • 如果在范围内,返回 方法区中的 cache[i + offset]
    • 如果超出范围,会在 堆内存 中创建新对象。

    3.3、关键点总结

    示例代码验证:

    // 127 在缓存范围内
    Integer a = 127;
    Integer b = 127;
    System.out.println(a == b); // true(a 和 b 指向方法区的同一个对象)
    
    // 128 超出缓存范围
    Integer c = 128;
    Integer d = 128;
    System.out.println(c == d); // false(c 和 d 指向堆中的不同对象)
    

    小结

    小结


    4、扩展知识

    4.1、缓存目的

    1. 性能优化
      小范围整数使用频繁,缓存可以避免重复创建对象,减少 GC 压力。

    2. 节省内存
      -128 到 127 有 256 个值,缓存后只需 256 个对象,而不是每次新建。

    3. 一致性
      在缓存范围内,== 和 equals() 行为一致,方便代码逻辑判断。

    4.2、BigInteger

           是 Java 提供的一个 任意精度的整数类,用于处理超出 int 或 long 范围的整数运算。它解决了 Java 基本数据类型(如 intlong)在处理 超大整数 时的 精度丢失 和 溢出 问题。

    1. 性能开销
      BigInteger 的运算速度比基本类型慢,适合 必须高精度 的场景(如密码学)。

    2. 不可变性
      每次运算都会生成新对象,频繁操作可能导致内存浪费。如果需要频繁修改,可以使用 BigDecimal(支持浮点数)。

    3. 线程安全
      由于不可变性,类似于String,BigInteger 是线程安全的,无需额外同步。

    4. 初始化方式

    BigInteger a = new BigInteger("12345678901234567890");
    

     
    

    应用场景:

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

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

    余额充值