基本类型数组内存占用远小于包装类型数组,因前者直接存储值且内存连续,后者需额外存储引用及每个包装对象的对象头、字段和对齐填充,导致内存放大近7倍并增加GC压力。

基本类型数组比包装类型数组内存占用小得多,核心原因在于前者直接存值,后者每个元素都是独立对象,带对象头和引用开销。
基本类型数组的内存结构
以 int[] 为例(10,000 个元素):
- 对象头固定 16 字节(64 位 JVM 启用压缩指针时:mark word 8 字节 + klass pointer 4 字节 + 数组长度 4 字节)
- 实例数据 = 10,000 × 4 字节 = 40,000 字节
- 对齐填充 = 0 字节(总大小 40,016 是 8 的倍数)
- 总计 ≈ 40,016 字节(约 39.08 KB)
包装类型数组的内存结构
以 Integer[] 为例(同样 10,000 个元素):
- 数组对象头仍为 16 字节
- 数组本身只存 10,000 个引用(每个引用在压缩指针下占 4 字节),共 40,000 字节
- 但每个 Integer 对象单独分配在堆上:对象头 16 字节 + int 值 4 字节 + 对齐填充 4 字节 = 24 字节/个
- 10,000 个 Integer 对象 → 10,000 × 24 = 240,000 字节
- 加上数组引用区 40,000 字节,总计 ≈ 280,016 字节(约 273.45 KB)
关键差异点
包装类型数组实际是“数组 + 一堆独立对象”的组合:
- 基本类型数组:一块连续内存,无额外对象开销
- Integer[] 不仅要存引用,还要为每个 Integer 分配完整对象空间,内存放大近 7 倍
- Long、Double 等包装类对象更大(通常 24 字节),差距更明显
- GC 压力也更高:10,000 个 Integer 是 10,000 个可被单独回收的对象
什么情况下必须用包装类型数组?
不是“想用就用”,而是场景驱动:
- 需要存储 null(如数据库字段可能为空)
- 要放进泛型集合(List<Integer>、Map<String, Integer>)
- 调用包装类特有方法(如 Integer.compare()、toString()、缓存逻辑)
- 使用反射或序列化框架要求对象类型








