-d64开关对Sun JVM驻留内存使用量有什么影响(如果有)?


问题内容

我有一个需要一些内存调整的webapp。尽管我已经对应用程序本身进行了概要分析并进行了精简,但在我们最繁忙的实例上,JVM本身似乎显得过分膨胀。(低容量实例不存在此问题。)详细信息:

  • 平台:
    • RHEL4 64位(Linux 2.6.9-78.0.5.ELsmp #1 SMP x86_64
    • Sun Java 6(Java HotSpot(TM) 64-Bit Server VM (build 10.0-b23, mixed mode)
    • 带有-d64in的Tomcat 6startup.sh
  • 我的webapp当前有一些代码在生产中需要运行64位的好处。
  • 我观察到,一段时间(一周)后,JVM的驻留内存大小(如顶部所示)是我的-Xmx设置的 三倍
  • 非堆内存大小等相对来说都是微不足道的,仅占堆大小的百分之几
  • 只有一段代码需要64位位地址空间

如果我可以重构对64位JVM的需求并放弃-d64开关,那是否会使JVM的驻留内存占用空间更小?换一种说法…

-d64 切换对Sun JVM驻留内存使用有什么影响(如果有)?


问题答案:

使用d64开关可使JVM进入64位模式。从技术上讲,在Solaris / Linux和大多数Unix上,JVM进程将以LP64模型执行。

LP64模型是从32位模型(ILP32)中的指针碰巧是64位宽的,而不是32位指针的不同。对于JVM,这允许更大的内存可寻址性,但这也意味着仅对象引用所占用的大小增加了一倍。因此,在给定的时间,在32位JVM和64位JVM中,相同数量的对象会有更大的膨胀。

经常被忘记的另一件事是指令本身的大小。在64位JVM上,指令的大小将占用本机寄存器的大小。

但是,如果您在64位环境中使用压缩对象指针,则对于堆大小大于4
GB的情况,JVM将尽可能对指针进行编码和解码。简而言之,当您使用压缩指针时,JVM会尝试尽可能多地使用32位宽的值。

提示:使用 -XX:+ UseCompressedOops
来打开UseCompressedOops标志,以消除某些膨胀。YMMV,但是人们报告说使用压缩的oops可使内存膨胀减少多达50%

编辑

Java HotSpot VM的14.0版支持UseCompressedOops标志,可从Java 6 Update
14开始使用