基元与盒装基元的内存消耗
原始 | 盒装型 | 内存/盒装的内存大小 |
---|---|---|
boolean |
Boolean |
1 字节/ 16 字节 |
byte |
Byte |
1 字节/ 16 字节 |
short |
Short |
2 个字节/ 16 个字节 |
char |
Char |
2 个字节/ 16 个字节 |
int |
Integer |
4 字节/ 16 字节 |
long |
Long |
8 字节/ 16 字节 |
float |
Float |
4 字节/ 16 字节 |
double |
Double |
8 字节/ 16 字节 |
盒装对象总是需要 8 个字节用于类型和内存管理,并且因为对象的大小总是 8 的倍数,所以盒装类型总共需要 16 个字节。在另外,盒装对象的每个的使用需要存储占另一个 4 或 8 个字节,这取决于 JVM 和 JVM 选项的参考。
在数据密集型操作中,内存消耗会对性能产生重大影响。使用数组时内存消耗增长更多:float[5]
数组只需要 32 个字节; 而存储 5 个不同的非空值的 Float[5]
将需要总共 112 个字节(在没有压缩指针的 64 位上,这增加到 152 个字节)。
盒装价值缓存
盒装值类型缓存可以在一定程度上减轻盒装类型的空间开销。一些盒装类型实现了实例的缓存。例如,默认情况下,Integer
类将缓存实例以表示 -128
到+127
范围内的数字。然而,这不会减少额外的存储器间接引起的额外成本。
如果通过自动装箱或通过调用静态 valueOf(primitive)
方法创建盒装类型的实例,运行时系统将尝试使用缓存值。如果你的应用程序在缓存的范围内使用了大量值,那么这可以大大减少使用盒装类型的内存损失。当然,如果你手动创建盒装值实例,最好使用 valueOf
而不是 new
。 (new
操作总是创建一个新实例。)但是,如果你的大多数值不在缓存范围内,则调用 new
并保存缓存查找会更快。