【问题标题】:JVM heap parametersJVM 堆参数
【发布时间】:2010-11-09 01:38:17
【问题描述】:

在阅读了关于该主题的已提出问题并进行了大量谷歌搜索后,我仍然无法清楚地了解 -Xms 选项

我的问题是:java -Xms=512m -Xmx=512mjava -Xms=64m -Xmx=512m 有什么区别?

现在我有以下答案:

唯一的区别是在我的应用程序运行期间将运行的垃圾回收数量和内存分配数量。我说的对吗?

这是我回答这个问题的原因:

-Xms 选项设置为512m 不会导致我的应用程序在启动后使用真正的512M 物理内存。我想这与现代操作系统虚拟内存管理和惰性页面分配有关。 (我注意到将-Xms 设置为512M64M 根本不会改变Linux 上的top 或Windows 上的任务管理器报告的初始使用内存)

有人可以帮助我了解此 Xms 选项的影响,或指向有助于我理解它的链接吗?

提前致谢

手动

【问题讨论】:

    标签: java jvm-arguments


    【解决方案1】:

    JVM 将从初始堆级别的内存使用开始。如果 maxheap 更高,它将增长到 maxheap 大小,因为内存需求超过了当前内存。

    所以,

    • -Xms512m -Xmx512m

    JVM 从 512 M 开始,从不调整大小。

    • -Xms64m -Xmx512m

    JVM 从 64M 开始,如果是 mem,则增长(最大上限为 512)。要求超过 64。

    【讨论】:

    • 我知道。但正如我在之前的评论中所说,“Java 将从初始堆级别的内存使用开始”究竟意味着什么?这个内存似乎没有得到有效分配,因为我的 512m 字节系统能够在不交换的情况下启动其他几个应用程序,并告诉我我的 java 应用程序只使用了几兆字节。
    • 如果您知道应用程序启动时会消耗特定数量的内存,通常会将初始堆大小设置为更大的值。这可以防止 JVM 在启动时花费执行时间来多次调整堆大小。这种特殊用途是一种非常常见的优化,通过避免昂贵的分配周期来使 eclipse 运行得更快。
    • 感谢这个答案让我想到另一个问题:将 Xms 值设置为与 Xmx 相同的值是否有任何“风险”或缺点?
    • 据我了解,唯一的风险是您会用完虚拟内存,因为您分配了太多虚拟内存 - 但如果您的应用程序真的需要内存,无论如何都会发生。
    • 我认为真正的语法是 -Xms64m 而不是 -Xms=64m。如果我记错了,请回滚!
    【解决方案2】:

    总结链接后找到的信息: JVM 分配 -Xms 指定的数量,但操作系统通常在需要时才分配实际页面。所以JVM按照Xms的规定分配虚拟内存,但只根据需要分配物理内存。

    您可以通过使用 Sysinternals 的 Process Explorer 而不是 Windows 上的任务管理器来查看这一点。

    因此,使用 -Xms64M 和 -Xms512M 之间存在真正的区别。 但我认为最重要的区别是你已经指出的那个:如果你真的需要 512MB 但只从 64MB 开始,垃圾收集器会运行得更频繁。

    【讨论】:

    • 我认为真正的语法是 -Xms64m 而不是 -Xms=64m。如果我记错了,请回滚!
    • 在研究 jvm 配置的一些细节时遇到了这个问题。这里接受的答案与我对这些价值观的理解有很大不同。是的,大多数操作系统只会在应用程序尝试访问它已分配的内存时触发轻微页面错误时才使物理页面可用 - 但 Xms 指定 jvm 分配的初始内存量 - 这在可以分配 应用程序分配更多内存的页面数 - 在 Java 的情况下,如果 gc 提供的内存不足,它只会分配更多内存(最多 Xmx)
    • @symcbean 我很困惑。看来您的理解与答案中的内容并没有真正的不同。您只是使用了不同的词,但描述了完全相同的行为。
    • 内存使用上限由 Xmx 设置,而不是 Xms。
    • @symcbean 问题是关于不同 Xms 值的不同行为以及为什么操作系统没有显示差异。根据我的回答(并在您的评论中确认),操作系统仅分配所需的物理内存,而不是应用程序最初分配的整个内存。 Java 将分配更多内存直到达到 Xmx 中的值这一事实完全没有受到质疑。
    【解决方案3】:

    除了标准的堆参数-Xms-Xmx 也很高兴知道-XX:PermSize-XX:MaxPermSize,它们用于指定Perm Gen 空间的大小,因为即使你可以在堆中的其他代中拥有空间如果您的 perm gen 空间已满,您可能会耗尽内存。这个链接也很好地概述了一些important JVM parameters

    【讨论】:

      【解决方案4】:

      JVM 自适应地调整堆大小,这意味着它将尝试为您的应用程序找到最佳的堆大小。 -Xms 和 -Xmx 只是指定 JVM 可以操作和调整堆大小的范围。如果 -Xms 和 -Xmx 是相同的值,那么 JVM 的堆大小将保持在该值不变。

      通常最好只设置 -Xmx 并让 JVM 找到最佳堆大小,除非有特定原因需要在 JVM 启动时给 JVM 一个大堆。

      至于 JVM 何时真正向操作系统请求内存,我相信这取决于 JVM 的平台和实现。我想在你的应用真正需要它之前它不会请求内存。 -Xmx 和 -Xms 只是保留内存。

      【讨论】:

        【解决方案5】:

        如果你写了: -Xms512m -Xmx512m 当它启动时,java 在那一刻为他的进程分配了 512m 的 ram 并且不能增加。

        -Xms64m -Xmx512m 启动时java只为他的进程分配64m的内存,但是java可以在512m的时候增加他的内存占用。

        我认为第二件事更好,因为您为 java 提供了自动内存管理。

        【讨论】:

        • 我知道。但是“Java 在那一刻分配 512m”到底是什么意思呢?这个内存似乎没有有效分配,因为我的 512m 字节系统能够在不交换的情况下启动其他几个应用程序,并告诉我我的 java 应用程序只使用了几兆字节..
        • 为什么这被否决了?它在技术上是正确的,除了最后一句可能正确也可能不正确。在高性能世界中,让 java 使用一个 brk() 分配所需的所有内存通常更聪明。在其他情况下,在使用时分配内存可能更聪明。
        • 我自己并没有否决这个答案。关于您的评论,我的问题与我向 dan 提出的问题相同:将 Xms 值设置为与 Xmx 相同的值是否有任何“风险”或缺点?谢谢马努
        • 将它们设置为相同的值是获得最佳性能的推荐方法。缺点是您需要格外小心,不要将它们设置得太高,因为这样做可能会影响系统的整体性能。
        • 我认为真正的语法是 -Xms64m 而不是 -Xms=64m。如果我记错了,请回滚!
        【解决方案6】:

        我在scalamy_file.scala 中创建了这个玩具示例:

        object MyObject {
        
            def main(args: Array[String]) {
                var ab = ArrayBuffer.empty[Int]
        
                for (i <- 0 to 100 * 1000 * 1000) {
                    ab += i
                    if (i % 10000 == 0) {
                        println("On : %s".format(i))
                    }
                }
            }
        }
        

        我运行它:

        scala -J-Xms500m -J-Xmx7g my_file.scala
        

        scala -J-Xms7g -J-Xmx7g my_file.scala
        

        -Xms500m 版本中肯定有明显的停顿。我很肯定短暂停是垃圾收集运行,而长暂停是堆分配。

        【讨论】:

          猜你喜欢
          • 2012-03-31
          • 1970-01-01
          • 1970-01-01
          • 2014-07-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-07
          相关资源
          最近更新 更多