JVM - 指针压缩

原理解释

在32位系统中,指针占4个字节。在64位系统中,指针占8个字节。更大的指针尺寸带来了:

  1. 更容易GC,因为占用空间更大了
  2. 降低CPU缓存命中率,因为一条cache line中能存放的指针数变少了

JVM - 对象的内存布局里提到,对象都是按照8字节对齐填充的,那么也就意味着指针的偏移量只会是8的倍数,而不会是下面中的1-7,只会是0或者8:

1
2
mem:  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
        ^                               ^

那么我们是否可以在堆中记录0x0、0x1偏移量来代表实际上的0x0、0x8呢?比如这样:

1
2
3
4
5
mem:  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
        ^                               ^
        |    ___________________________|
        |   |
heap: | 0 | 1 |

答案是可以的。你只需在从heap里拿出来的时候做一下翻译,像左位移3位,就得到了在内存中实际位置。放到heap中的时候只需右移3位,就得到了在heap中记录的位置。

JVM启用指针压缩后(默认开启),指针大小从8字节变成了4字节,也就是32位,而这个32位实际上能表达的地址范围是235=32G。

JVM参数

开启压缩(默认开启的):-XX:+UseCompressedOops

关闭压缩:-XX:-UseCompressedOops

参考资料

版权

评论