Java -Xmx,系统最大内存

问题描述 投票:0回答:7

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

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

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

java memory-management
7个回答
13
投票

在 32 位 Windows 上,-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 更擅长做到这一点,不那么混乱(但它们也有更好的垃圾收集器)

如果您无法减少内存消耗(我知道这有多难),那么就拥有大量物理内存并分配其中的大部分。


5
投票

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

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 上测试它时它都有效。



0
投票

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

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

这需要大量的内存和大量的交换空间(当时)以及较旧的 Java 虚拟机,因此您的情况可能会有所不同。

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


0
投票

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


0
投票

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

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

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

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


0
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.