当前位置:网站首页>JVM 的指针压缩
JVM 的指针压缩
2022-06-27 00:47:00 【唐伯虎点蚊香dw】
在介绍完关于内存对齐的相关内容之后,我们来介绍下前边经常提到的压缩指针。可以通过JVM参数XX:+UseCompressedOops开启,当然默认是开启的。
在本小节内容开启之前,我们先来讨论一个问题,那就是为什么要使用压缩指针??
假设我们现在正在准备将32位系统切换到64位系统,起初我们可能会期望系统性能会立马得到提升,但现实情况可能并不是这样的。
在JVM中导致性能下降的最主要原因就是64位系统中的对象引用。在前边我们也提到过,64位系统中对象的引用以及类型指针占用64 bit也就是8个字节。
这就导致了在64位系统中的对象引用占用的内存空间是32位系统中的两倍大小,因此间接的导致了在64位系统中更多的内存消耗以及更频繁的GC发生,GC占用的CPU时间越多,那么我们的应用程序占用CPU的时间就越少。
另外一个就是对象的引用变大了,那么CPU可缓存的对象相对就少了,增加了对内存的访问。综合以上几点从而导致了系统性能的下降。
从另一方面来说,在64位系统中内存的寻址空间为2^48 = 256T,在现实情况中我们真的需要这么大的寻址空间吗??好像也没必要吧~~
于是我们就有了新的想法:那么我们是否应该切换回32位系统呢?
如果我们切换回32位系统,我们怎么解决在32位系统中拥有超过4G的内存寻址空间呢?因为现在4G的内存大小对于现在的应用来说明显是不够的。
我想以上的这些问题,也是当初JVM的开发者需要面对和解决的,当然他们也交出了非常完美的答卷,那就是使用压缩指针可以在64位系统中利用32位的对象引用获得超过4G的内存寻址空间。
7.1 压缩指针是如何做到的呢?
还记得之前我们在介绍对齐填充和内存对齐小节中提到的,在Java虚拟机堆中对象的起始地址必须对齐至8的倍数吗?
由于堆中对象的起始地址均是对齐至8的倍数,所以对象引用在开启压缩指针情况下的32位二进制的后三位始终是0(因为它们始终可以被8整除)。
既然JVM已经知道了这些对象的内存地址后三位始终是0,那么这些无意义的0就没必要在堆中继续存储。相反,我们可以利用存储0的这3位bit存储一些有意义的信息,这样我们就多出3位bit的寻址空间。
这样在存储的时候,JVM还是按照32位来存储,只不过后三位原本用来存储0的bit现在被我们用来存放有意义的地址空间信息。
当寻址的时候,JVM将这32位的对象引用左移3位(后三位补0)。这就导致了在开启压缩指针的情况下,我们原本32位的内存寻址空间一下变成了35位。可寻址的内存空间变为2^32 * 2^3 = 32G。

压缩指针.png
这样一来,JVM虽然额外的执行了一些位运算但是极大的提高了寻址空间,并且将对象引用占用内存大小降低了一半,节省了大量空间。况且这些位运算对于CPU来说是非常容易且轻量的操作
通过压缩指针的原理我挖掘到了内存对齐的另一个重要原因就是通过内存对齐至8的倍数,我们可以在64位系统中使用压缩指针通过32位的对象引用将寻址空间提升至32G.
从Java7开始,当maximum heap size小于32G的时候,压缩指针是默认开启的。但是当maximum heap size大于32G的时候,压缩指针就会关闭。
那么我们如何在压缩指针开启的情况下进一步扩大寻址空间呢???
7.2 如何进一步扩大寻址空间
前边提到我们在Java虚拟机堆中对象起始地址均需要对其至8的倍数,不过这个数值我们可以通过JVM参数-XX:ObjectAlignmentInBytes 来改变(默认值为8)。当然这个数值的必须是2的次幂,数值范围需要在8 - 256之间。
正是因为对象地址对齐至8的倍数,才会多出3位bit让我们存储额外的地址信息,进而将4G的寻址空间提升至32G。
同样的道理,如果我们将ObjectAlignmentInBytes的数值设置为16呢?
对象地址均对齐至16的倍数,那么就会多出4位bit让我们存储额外的地址信息。寻址空间变为2^32 * 2^4 = 64G。
通过以上规律,我们就能知道,在64位系统中开启压缩指针的情况,寻址范围的计算公式:4G * ObjectAlignmentInBytes = 寻址范围。
但是笔者并不建议大家贸然这样做,因为增大了ObjectAlignmentInBytes虽然能扩大寻址范围,但是这同时也可能增加了对象之间的字节填充,导致压缩指针没有达到原本节省空间的效果。
边栏推荐
- memcached基础6
- 在线文本数字识别列表求和工具
- Memcached foundation 6
- Flutter series: flow in flutter
- 大白话高并发(一)
- 清华&智源 | CogView2:更快更好的文本图像生成模型
- Memcached foundation 4
- These 10 copywriting artifacts help you speed up the code. Are you still worried that you can't write a copywriting for US media?
- MySQL之账号管理、建库以及四大引擎+案例
- The world is very big. Some people tattoo QR codes on their necks
猜你喜欢
随机推荐
Great vernacular with high concurrency (I)
getReader() has already been called for this request
做了两天的唯美蝴蝶动画
用代码生成流程图,Markdown的使用方法
通过Rust语言计算加速技术突破图片识别性能瓶颈
Memcached foundation 2
Gaussian and Summary Stats
uvm中的config机制方法总结(一)
memcached基础5
UVM中uvm_report_enabled的用法
Analysis of ideal L9 product power: the price is 459800 yuan, the four cylinder engine is adopted, and the endurance is 1315km
Keepalived 实现 Redis AutoFailover (RedisHA)17
How to measure the thickness of glass substrate by spectral confocal
Live review | Ziya &ccf TF: Discussion on software supply chain risk management technology under cloud native scenario
LeetCode 142. 环形链表 II
Buuctf PWN write UPS (6)
memcached基础3
ESP32实验-自建web服务器配网02
Flutter series: flow in flutter
getReader() has already been called for this request









