Java-Xmx,系统上的最大内存

Java-Xmx,系统上的最大内存,java,memory-management,Java,Memory Management,我的Java应用程序通过运行进程“Java-jar j.jar”运行另一个Java应用程序。众所周知,根据给定的数据集,J.jar会使用大量内存,并且经常会得到OutOfMemoryError堆。所以我想在它上面使用-Xmx,这样我就可以分配尽可能多的内存(或者接近内存)。我在考虑获取系统上的总内存,然后在-Xmx中指定80-90%的内存 我的问题有什么解决办法吗?我的解决方案听起来怎么样 编辑:我无法减少内存消耗,因为使用的内存是Java内置的pack200压缩,我用它来打包一些JAR文件。好

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

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


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

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

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

这需要大量的ram和大量的交换空间(暂时)以及一个旧的Java虚拟机,因此您的里程可能会有所不同


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

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

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


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

JProfiler非常漂亮,但是您可以使用HPROF获得相同的信息,HPROF是在Java 5中引入的:

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


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

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

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

在32位Windows上,-XmX的限制是-Xmx1500m。 共享库妨碍了更大的堆。 要做到这一点,您需要大约2Gb的RAM

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

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

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

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

另一位评论者是对的,分页JVM内存中的映像并不快。 后来的JVM更擅长于减少混乱(但它们也有更好的垃圾收集器)

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

-XX:DefaultMaxRAMFraction=1


那么您实际上是在问如何使用Java来确定系统内存量?是的,这将是一个可能的解决方案,如果您知道一种方法,知道这一点将不胜感激。您是否运行64位jvm?因为如果你运行32位,那么如果你的免费MEM变成7G,那么你将遇到“80%”位的问题,例如,是否有一个C++的等价物??分配给JVM的可用内存应该基于数据集的大小,而不是本地主机上的(完全正交)可用内存。对于独立于本地内存的可扩展解决方案,请使用分布式缓存。启动其他应用程序或启动我的应用程序也会带来相同的问题。如果我用它的主方法运行另一个应用程序,我仍然需要我的应用程序能够使用大量内存。谢谢!我在Windows和Linux上试过这个命令,效果非常好。看起来这只在sun JVM上有效,我需要部署到IBM JVM,所以不能在每个人都使用sun的情况下运行。