【问题标题】:Java -Xmx, Max memory on systemJava -Xmx,系统最大内存
【发布时间】:2010-11-14 12:27:57
【问题描述】:

我的 Java 应用程序通过运行“java -jar j.jar”进程来运行另一个 Java 应用程序。众所周知,J.jar 会根据给定的数据集使用大量内存,并且经常会获得 OutOfMemoryError 堆。所以我想在它上面使用-Xmx,这样我就可以分配尽可能多的内存(或接近)。我正在考虑获取系统上的总内存,然后在 -Xmx 中指定其中的 80-90%。

我的问题有什么解决办法吗?而且,我的解决方案听起来如何?

编辑:我无法减少内存消耗,因为正在使用的内存是 Java 的内置 pack200 压缩,我用它来打包一些 JAR 文件。

【问题讨论】:

  • 那么你实际上是在问如何使用Java来确定系统内存量?
  • 是的,这将是一种可能的解决方案,如果您知道方法,将不胜感激。
  • 您运行的是 64 位 jvm 吗?因为如果你运行的是 32 位,那么如果你的免费内存变成 7G,那么“80%”位就会出现问题,例如
  • 是否有 C++ 的等价物???
  • 分配给 jvm 的可用内存应该基于数据集的大小,而不是本地主机上的(完全正交的)可用内存。对于独立于本地内存的可扩展解决方案,请使用分布式缓存。

标签: java memory-management


【解决方案1】:

在 32 位窗口上 -XmX 的限制是 -Xmx1500m。 共享库阻碍了更大的堆。 您需要大约 2Gb 的 RAM 才能执行此操作。

在非 Windows 操作系统上,您可以做得更大,而 64 位 JVM 可以做得更多。

Windows XP 不会让您拥有超过 3Gb 的 RAM(不管您是否拥有 4Gb 物理内存,从 XP SP3 开始) Vista 可能与 YMMV 不同。

我已经在 64 位 Linux 上的 64 位 JVM 上尝试了 -Xmx4000M,它很好。 考虑到我有 6Gb 的物理内存,这不是一个大要求。

您的 80% 想法很有趣,但我的测试系统运行的百分比比没有不良影响的要高。 (只要你不尝试做任何其他事情。)

另一位评论者是对的,分页出 JVM 的内存映像并不快。 后来的 JVM 在这方面做得更好(但他们也有更好的垃圾收集器)

如果您不能减少内存消耗——我知道这有多难——那么拥有大量的物理内存并分配其中的大部分。

【讨论】:

    【解决方案2】:

    根据您的操作系统,这可能适用于获取空闲和可用内存大小:

    java.lang.management.OperatingSystemMXBean mxbean = java.lang.management.ManagementFactory.getOperatingSystemMXBean();
    com.sun.management.OperatingSystemMXBean sunmxbean = (com.sun.management.OperatingSystemMXBean) mxbean;
    long freeMemory = sunmxbean.getFreePhysicalMemorySize();
    long availableMemory = sunmxbean.getTotalPhysicalMemorySize();
    

    从那里,您可以计算出 80-90% 并以您想要的最大内存大小启动您的 jar。

    我不知道这适用于所有操作系统(即 Windows),但是当我在 OSX 和 Linux 上测试它时它都有效。

    【讨论】:

    • 谢谢!我在 Windows 和 Linux 上试过这个命令,效果很好。
    • 貌似这个只能在sun JVM上运行,我需要部署到IBM JVM,所以不能运行每个都会用sun的。
    【解决方案3】:
    -XX:DefaultMaxRAMFraction=1
    

    bugs.sun.com
    Sun's 1.5 JVM

    【讨论】:

      【解决方案4】:

      嗯,我可以告诉你的一件事是不要让你的应用程序接近填满 ram。 Java 应用程序根本不能优雅地交换。我认为由于垃圾收集,java 不断地从交换中提取它的内存。

      我遇到了一个死锁,我认为系统正在向 java 请求内存,这会导致 GC 并将内容从交换文件中拉出——此时系统只会旋转,直到我重置它。

      这是有大量内存和大量交换空间(当时)和较旧的 Java VM,因此您的里程可能会有所不同。

      此外,根据您启动其他应用的方式,您可能必须为您的应用指定 -Xms 而不是另一个。如果你给它一个完整的命令,给它 -Xms,但如果你只是调用 jar 中的主类,那么你的应用程序需要 -Xms。 (哦,你指定了,是的,你需要将它传递给你正在调用的“Java”命令。)

      【讨论】:

        【解决方案5】:

        您使用操作系统执行 jar 中的程序是否有原因?如果您不需要它在与您的应用程序不同的进程中执行,您可以直接从您的代码中调用 main 方法,然后使用您想要的任何 -Xmx 启动您的应用程序。

        【讨论】:

        • 启动其他应用程序或启动我的应用程序会产生相同的问题。如果我使用它的 main 方法运行另一个应用程序,我仍然需要我的应用程序能够使用大量内存。
        【解决方案6】:

        如果您还没有这样做,您需要通过内存分析器运行您的程序。您可能会发现某些数据结构并没有被丢弃,即使它们不再被使用。

        JProfiler 非常漂亮,但是您可以使用 Java 5 中引入的 HPROF 获得相同的信息:http://java.sun.com/developer/technicalArticles/Programming/HPROF.html

        还要记住,不同的平台具有不同的最大堆大小,这取决于架构(32 位与 64 位)、操作系统,甚至 JVM。

        如果您有很多可以重用的值(例如从 XML 文件中读取的字符串),那么通过池化对象可以大大减少内存需求。

        【讨论】:

          【解决方案7】:

          在下面的blog 中有一篇关于如何使用 jconsole 和其他工具对 java 应用程序进行故障排除的完整博客文章。请记住,缺乏对内存使用的控制很可能是内存泄漏,但也可能是由于其他原因。查看帖子,尝试复制该场景,看看是否解决了您的问题。

          http://www.kiragiannis.com/cloud-computing/debug-a-java-application-in-the-cloud/

          【讨论】:

            猜你喜欢
            • 2012-08-08
            • 2012-08-30
            • 2018-05-02
            • 1970-01-01
            • 2013-05-24
            • 2013-11-11
            • 2011-05-19
            • 2011-02-20
            • 2020-04-09
            相关资源
            最近更新 更多