【问题标题】:JVM won't use as much memory as I tell it toJVM 不会像我说的那样使用内存
【发布时间】:2014-08-19 20:57:29
【问题描述】:

我正在运行一个内存密集型应用程序。关于环境的一些信息:

  • 64位debian
  • 13 GB 内存
  • 64 位 JVM(我在程序运行时输出 System.getProperty("sun.arch.data.model"),显示为“64”)

这是我发出的确切命令:

java -Xmx9000m -jar "ale.jar" testconfig

我已经在其他几个系统上使用完全相同的数据、配置等运行程序,并且我知道 JVM 在这些系统上使用(在其峰值)6 GB 内存。但是,我收到 OutOfMemory 错误。此外,在程序执行期间,系统的可用内存永远不会低于 8.5 GB。

当我在执行期间输出 Runtime.getRuntime().maxMemory() 时,我得到的值是 3044540416,即 ~ 3 GB。

我不知道它是否相关,但这是一个 Google Compute Engine 实例。

我能想到的唯一解释是,单个进程可以使用的最大内存量可能存在某种系统限制。

【问题讨论】:

  • 试试 java -Xms9g -Xmx9g -jar [...],这对我有用。
  • 您收到的完整异常消息是什么?什么是堆栈跟踪?
  • 使用-XX:+PrintGCDetails 查找实际的堆布局。

标签: java memory jvm


【解决方案1】:

我能想到的唯一解释是,单个进程可以使用的最大内存量可能存在某种系统限制。

这是一种可能的解释。

另一个是你试图分配一个非常大的数组。可能的最大数组是2^31 - 1 元素,但实际大小取决于元素大小:

  • byte[]boolean[] ... 2G 字节
  • char[]short[] ... 4G 字节
  • int[] ... 8 GB
  • long[]Object[] ... 16 GB

如果您分配了一个非常大的数组,GC 需要找到所需大小的连续可用内存区域。根据数组的大小,以及堆空间被分割成空间的方式,它可能能够找到比你想象的要少得多的连续空间。

第三种可能性是您获得了 OOME,因为 GC 运行 GC 的时间达到了 GC Overhead 限制。


如果您向我们展示堆栈跟踪,其中一些理论可能会得到证实或驳回......

【讨论】:

    【解决方案2】:

    -Xmx 只会设置最大分配内存。使用 -Xms 指定最小值。将它们设置为相同的值将使内存占用保持不变。

    【讨论】:

      猜你喜欢
      • 2013-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多