JVM中的压缩OOP
Posted SpringForAll社区
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM中的压缩OOP相关的知识,希望对你有一定的参考价值。
1 简介
JVM为我们管理内存,这减轻了开发人员的内存管理负担,因此我们不需要手动操作对象指针,这被证明是耗时且容易出错的。
在幕后,JVM结合了许多漂亮的技巧来优化内存管理过程。一个技巧是使用压缩指针,我们将在本文中对其进行评估。首先,让我们看看JVM如何在运行时表示对象。
2 运行时表示对象
HotSpot JVM使用名为oops或Ordinary Object Pointers的数据结构来表示对象。这些oops等同于本地C指针。instanceOops是一种特殊的oop,表示Java中的对象实例。此外,JVM还支持其他少数oops在OpenJDK source tree保存。
让我们看看在JVM中instanceOops在内存中如何分布。
2.1 对象内存布局
instanceOop的内存布局很简单:它只是对象头后面紧跟零个或多个对实例字段的引用。
JVM中对象头对象头表示包括:
标记词,用于许多目的,如偏置锁定,身份哈希值和GC。它不是一个oop,但由于历史原因,它存在于OpenJDK的oop源代码树中。
Klass词,表示指向类元数据的指针。在Java 7之前,它们是在永久代中保留的,但是从Java 8开始,它们就在Metaspace中。
32位长度字,仅数组字段,表示数组长度。
32位的间隔来强制对象对齐。这会让事情变得更容易,我们稍后会看到。
在头部之后,对实例字段有零个或多个引用。在这种情况下,单字就是本机机器字,因此在传统的32位机器上为32位,在更现代的系统上为64位。
2.2 垃圾剖析
假设我们要从传统的32位架构切换到更现代的64位机器。起初,我们可能希望立即获得性能提升。但是,当涉及JVM时并非总是如此。
这种可能性能下降的主要原因是64位对象引用。64位引用比32位引用的多占用两倍空间,因此这会导致更多的内存消耗和更频繁的GC周期。专用于GC周期的时间越多,应用程序线程的CPU执行切片就越少。
那么,我们应该切换回来并再次使用这些32位架构吗?即使这是一个选项,我们无论多做多少工作也无法在32位进程空间中拥有超过4 GB的堆空间。
3 压缩OOPs
事实证明,JVM可以通过压缩对象指针或oops来避免浪费内存,因此我们可以充分利用这两个方面:在64位计算机中允许超过4 GB的堆空间和32位引用!
3.1 基本优化
正如我们之前看到的,JVM为对象进行填充,使其大小变为8个字节的倍数。使用这些填充后,oops中的最后三位始终为零。这是因为在二进制中8的倍数的数字总是以000结尾。
为了使这种优化工作,当JVM需要在内存中找到一个对象时,它将指针向左移动3位(基本上将这些3-zero重新加到最后)。另一方面,当向堆加载指针时,JVM将指针向右移动3位以丢弃先前添加的零。基本上,JVM执行更多的计算以节省一些空间。幸运的是,对于大多数CPU来说,位移是一个非常简单的操作。
要启用oop压缩,我们可以使用标志-XX:+ UseCompressedOops进行调整。只要最大堆大小小于32 GB,Java 7以上的默认开启oop压缩。当最大堆大小超过32 GB时,JVM将自动关闭oop压缩。因此,需要以不同方式管理超过32 Gb堆大小的内存利用率。
3.2 超过32 GB
当Java堆大小大于32GB时,也可以使用压缩指针。虽然默认对象对齐是8个字节,但可以使用-XX:ObjectAlignmentInBytes配置字节值。指定的值应为2的幂,并且必须在8和256的范围内。
我们可以使用压缩指针计算最大可能的堆大小,如下所示:
4 GB * ObjectAlignmentInBytes
例如,当对象对齐为16个字节时,通过压缩指针最多可以使用64 GB的堆空间。
请注意,随着对齐值的增加,对象之间未使用的空间也会增加。因此,我们可能没有意识到使用大Java堆大小的压缩指针会带来什么好处。
3.3 未来的GCS
ZGC是Java 11中的新增功能,是一个实验性和可扩展的低延迟垃圾收集器。它可以处理不同范围的堆大小,同时保持GC暂停低于10毫秒。由于ZGC需要使用64位彩色指针,因此它不支持压缩引用。因此,使用像ZGC这样的超低延迟GC必须使用更多内存再次进行交易。
4 结束语
在本文中,我们描述了64位体系结构中的JVM内存管理问题。我们了解了压缩指针和对象对齐,并了解了JVM如何解决这些问题,允许我们使用更大的堆减少浪费的指针和获得最少的额外计算。
原文链接:https://www.baeldung.com/jvm-compressed-oops
译者:Emma
推荐:
上一篇:
关注公众号
点击原文阅读更多
以上是关于JVM中的压缩OOP的主要内容,如果未能解决你的问题,请参考以下文章