0
点赞
收藏
分享

微信扫一扫

不需要再手工指定JVM启动参数-XX:+UseCompressedOops


技术团队通过 ​​GCeasy​​ 工具分析完几千次用户上传的GC日志后, 发现一个现象: 仍然有很多Java程序传入了JVM启动参数 ​​-XX:+UseCompressedOops​​。

实际上,如果JVM的版本在 Java SE 6 update 23 及以上, 则不需要再设置 ​​-XX:+UseCompressedOops​​ 参数, 因为默认会开启。

“OOP” 表示普通对象指针(Ordinary Object Pointer), 这种指针是对某个对象的托管指针(managed pointer)。 OOP占用的空间长度通常与宿主机的原生指针(native machine pointer)一样; 也就是说, 在64位操作系统上OOP就是64位, 在32位操作系统上OOP就占32位。

由于操作系统的限制,32位版本的JVM, 内存地址空间最大只能到 4GB(​​2 ^ 32​​字节)。

如果要管理更大的内存,需要使用64位JVM。

而如果JVM使用64位OOP,则最多可以管理 18.5 Exabytes(​​2 ^ 64​​字节)。

这是一个非常大的空间。 当今世界上还没有哪台服务器有这么大的物理内存。


那么问题来了: 64位JVM上, 使用32位的压缩指针如何管理32GB内存呢?
我们可以注意到 4x8=32; 想一下, 如果内存地址使用8字节对齐(8x8=64bit), 再进行映射和换算, 是不是就可以放大8倍了?
当然, 这样处理的话, 要更精细的操作单个字节就不容易了。
想要了解JVM的内存布局和对齐机制, 可以参考: ​​解析一个Java对象占用多少内存空间​​


存储指针的内存空间放大1倍,可以定位更大的内存区域。

但这并非 “没有代价”。

从32位JVM切换到64位JVM,你会发现可用内存的消耗会变成原来的1.5倍左右, 这是因为存储地址指针的空间消耗变大了。

为了解决这个问题,JVM开发人员发明了 ​​Compressed Oops​​ 功能。 关于压缩指针(compressed OOPs)的详细信息请参考: ​​HotSpot JVM Performance Enhancements
​​ 。

要启用这个功能,可以传入JVM启动参数 ​​-XX:+UseCompressedOops​​。

但从 Java SE 6U23 开始,JVM会默认开启压缩指针。

因此, 我们不需要再手动传递这个参数。


  • 原文链接: ​​Avoid passing -XX:+UseCompressedOops​​
  • GitHub版本: ​​不需要再手工指定JVM启动参数 ​​-XX:+UseCompressedOops​​​
  • Gitee版本: ​​不需要再手工指定JVM启动参数 ​​-XX:+UseCompressedOops​​​


举报

相关推荐

0 条评论