java - 64 位 Linux 上的意外 JVM 行为

标签 java jvm 32bit-64bit

我尝试比较我的 Java Web 应用程序在 32 位 Windows 和 64 位 Linux 上的行为。

当我通过 jconsole 查看内存使用情况时,我发现内存使用情况的图表非常不同。 在 Windows 上,应用程序永远不会触及 512m。 然而,当我在带有 64 位 VM 的 linux 64 位上运行时,内存不断增加并很快达到约 1000m 的峰值,并且我还收到与超出 GC 超额限制相关的 oome 错误。在 Linux 上,每当我手动运行 GC 时,它就会下降到不到 100m。

GC 看起来确实像在 Windows 上运行得那么好。

在 Windows 上,应用程序在负载更大的情况下运行得更好。

如何找到这背后的原因?

我使用jdk1.6.0.13

最小堆:512m,最大堆1024m

编辑:

  • 您在 Windows 和 Linux 上使用相同的 JVM 版本吗?

    • 是。1.6.0.13。
  • 您在两个系统上使用相同的垃圾收集器吗?

    • 我注意到 jconsole 中的 gc 是不同的。
  • 您在两个系统上使用相同的 Web 容器吗?

    • 是的,Tomcat。
  • 您的网络应用程序是否依赖 native 库?

    • 不确定。我用的是tomcat+spring+hibernate+jsf。
  • 这两个平台上的 Web 应用程序配置还有其他差异吗? 没有

  • 与 OOME 相关的错误消息到底是什么?

    • java.lang.OutOfMemoryError:超出 GC 开销限制
  • 您的网络应用程序需要多长时间才能在 Linux 上开始行为不当/报告错误?

    • 在我让其运行 3 小时后,可以看到使用模式的差异。该错误大约在一天或两天后出现,因为此时平均内存使用量约为 900 MB。

最佳答案

64 位 JVM 自然会比 32 位 JVM 使用更多的内存,这是可以预料的(毕竟,内部指针的大小是其两倍)。从 32 位迁移到 64 位时,您无法保持相同的堆设置并期望出现相同的行为。

如果您的应用程序在 32 位 JVM 上以 512m 的速度运行良好,则没有任何理由使用 64 位 JVM。这样做的唯一理由是利用巨大的堆大小。

请记住,在 64 位操作系统上运行 32 位 JVM 是完全有效的。两者没有关系。

关于java - 64 位 Linux 上的意外 JVM 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3378749/

相关文章:

objective-c - 在 32 位和 64 位上编码/解码 CGFloat

c# - 创建 64 位应用程序

xcode - CIFilter 在为 32 位构建时可以工作,但在为 64 位构建时不会出现?

java - Java 可以不用 JVM 编译源代码吗?

c++ - 是否有可能像 Java 一样通过在 VM 中运行来使 C++ 平台独立?

java - 使用键值对解析字符串响应并将它们添加到映射或数组中

java - 使用 JAXB 解码 XML 后无法获取正确的值

java - 整数不等于时不进行比较

java - 如何在 XML 中嵌入二进制数据?

java - 为什么 Java 运行时在 SSL 信任存储的工作方式以及我们如何处理它方面存在如此大的差异?