最初的时候,JVM是32位的,但是随着64位系统的兴起,JVM也迎来了从32位到64位的转换,32位的JVM对比64位的内存容量比较有限,但是我们使用64位虚拟机的同时,也带来了一个问题,64位下的JVM中的对象会比32位中的对象多占用1.5倍的内存空间,这是我们不想看到的(又要马儿跑,又要马儿不吃草可还行?),但是机智的程序员不会屈服,所以在JDK 1.6的版本后,我们在64位中的JVM中可以开启指针压缩(UseCompressedOops)来压缩我们对象指针的大小来帮助我们节约内存空间,拿JDK 8来说,这个指令是默认开启的。
如果我想要知道我们电脑上安装的JVM是32位的还是64位的,可以通过下面的这个命令去查看
如果我们的系统是64位的,当我们输入 java-d32
的时候会提示不支持32位的JVM,或者我们通过 java-version
也可以看到:
当我们启用了 -XX:+UseCompressedOops
之后,我们原本的OOP(Ordinary Object Pointer,普通对象指针)就会被压缩,当然也不是所有的对象都会被压缩,只有 以下几种的对象才会被压缩
对象的 全局静态变量 (类属性)
对象头信息
对象的引用类型
对象数组类型
而以下几种对象则不能被压缩:
指向PermGen的Class对象指针
局部变量
传参
返回值
NULL指针
指针压缩的大概原理:
通过对齐,还有偏移量将64位指针压缩成32位。
零基压缩是针对压缩解压动作的进一步优化。 它通过 改变正常指针的随机地址分配特性 , 强制堆地址从零开始分配 。
这里需要注意:32位HotSpot VM是不支持UseCompressedOops参数的,只有64位HotSpot VM才支持。