1.基本数据类型
java中的9种基本类型包括boolean,byte,char,shor,int,long,float,double和refvar.
前8种数据类型表示生活中的真假,字符,整数和小数.最后一种refvar是面向对象世界中的引用变量,也叫引用句柄.
2.基本类型refvar
引用分成两种数据类型: 引用变量本身和引用指向的对象.为了强化这两个概念的区分,把引用变量(Reference Variable) 称为 refvar, 而把引用指向的实际对象(Referred Object) 简称为 refobj.
refvar的默认值为null,存储 refobj 的首地址,可以直接使用双等号 == 进行等值判断.
作为一个引用变量,不管它是指向包装类,集合类,字符串类还是自定义类, refvar 均占用4B 空间,注意它与真正对象refobj之间的区别.无论refobj 是多么小的对象,最小占用的存储空间是12B(用于存储基本信息,称为对象头) , 但由于存储空间分片必须是8B的倍数,所以初始分片的空间至少是16B.
3. 对象内部存储
对象分为三块存储区域:
3.1 对象头(Object Header)
对象头占用12B个字节,存储内容包括对象标记(markOop)和类元信息(klassOop).
对象标记存储本身运行时的数据,如哈希码,GC 标记,GC次数,锁信息,线程关联信息等,这部分数据在64位JVM上占用8个字节,称为"Mark Work" .为了存储更多的状态信息,对象标记的存储格式是非固定的(具体与JVM的实现有关).类元信息存储的是对象指向它的类元信息(即Klass)的首地址,占用4个字节,与refvar开销一致.
3.2 实例数据(Instance Data)
存储本类对象的实例成员变量和所有可见的父类成员变量.如Integer 的实例成员只有一个 private int value,占用4个字节,所以加上对象头为16个字节.
3.3 对齐填充(Padding)
对象的存储空间分配单位是8个字节,如果一个占用大小为16个字节的对象,增加一个成员变量byte 类型,此时需要占用17个字节,但是也会分配24个字节进行对齐填充操作.
4. 包装类型
包装类的存在解决了基本数据类型无法做到的事情: 泛型类型参数,序列化,类型转换,高频区间数据缓存.
推荐所有包装类对象之间值的比较,全部使用equals()方法.
4.1 Integer
缓存范围是 -128~127, 但它是唯一可以修改缓存范围的包装类,在VM options 加入参数 -XX:AutoBoxCacheMax=7777,即可设置最大缓存值为7777.
4.2 包装类和基本数据类型
在选择使用包装类还是基本数据类型时,推荐使用如下方式:
1.所有的POJO类属性必须使用包装数据类型.
2.RPC方法的返回值和参数必须使用包装数据类型.
3.所有的局部变量推荐使用基本数据类型.