关于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类型来处理超大整数 时的 精度丢失 和 溢出 问题。int Integer


1、int 和 Integer区别

如下图所示:

1.1int 的大小

 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博客文章浏览阅读903次,点赞20次,收藏26次。本文详细探讨了Java虚拟机(JVM)中对象的内存结构、垃圾回收(GC)机制以及对象晋升策略。首先,介绍了普通对象和数组对象的内存布局,包括对象头(MarkWord和ClassPointer)和实例数据的存储方式。接着,分析了GC在不同内存区域(新生代、老年代、元空间)的发生条件及对象晋升的规则,特别是通过15次MinorGC后对象从新生代晋升到老年代的设计。此外,文章还讨论了如何通过调整Survivor区大小或使用G1垃圾回收器来优化对象存活时间。最后,总结了JVM在设计GC年龄机制时如何在性能、内存效率 https://blog.csdn.net/weixin_50055999/article/details/147988062?spm=1011.2415.3001.5331

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

示例

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

1.3、内存大小

   Integer 是对象,包含 对象头(类型指针、MarkWord)、字段(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 数组是 静态变量

    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 指向堆中的不同对象)
    

    小结

    小结

    -128 127


    4、扩展知识

    4.1、缓存目的

    1、性能优化

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

    2、节省内存

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

    3、一致性

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

    4.2、BigInteger

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

    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、付费专栏及课程。

    余额充值