我的Java应用程序通过运行“java -jar j.jar”进程运行另一个Java应用程序。众所周知,J.jar根据给定的数据集使用大量内存,并且通常会获得OutOfMemoryError堆。所以我想在它上面使用-Xmx,这样我就可以分配尽可能多的内存(或接近)。我想在系统上获取总内存,然后在-Xmx中指定80-90%的内存。
我的问题有解决办法吗?而且,我的解决方案如何发声?
编辑:我不能减少内存消耗,因为正在使用的内存是Java的内置pack200压缩,我用它来打包一些JAR文件。
答案 0 :(得分:13)
32位窗口上-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并分配大部分内存。
答案 1 :(得分:5)
-XX:DefaultMaxRAMFraction=1
答案 2 :(得分:4)
根据您的操作系统,这可能有助于获得可用和可用的内存大小:
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进行测试时,它都能正常工作。
答案 3 :(得分:0)
好吧,我可以告诉你的一件事是不要让你的应用程序接近填满ram。 Java应用程序根本不会优雅地交换。我认为,由于垃圾收集,java不断从交换中获取内存。
我遇到了僵局,我认为系统正在向java询问内存,这会导致GC并从交换文件中取出内容 - 此时系统会旋转直到我重置它。
这有很多ram和很多交换空间(当时)和较旧的Java VM,所以你的里程可能会有所不同。
此外,根据您启动其他应用的方式,您可能必须为您的应用指定-Xms而不是另一个应用。如果你给它一个完整的命令,给它-Xms,但如果你只是在jar中调用主类,那么你的应用需要-Xms。 (哦,你指定了,是的,你需要将它传递给你正在调用的“Java”命令。)
答案 4 :(得分:0)
您是否有理由使用操作系统在jar中执行程序?如果您不需要在应用程序的单独进程中执行它,则可以直接从代码中调用main方法,并使用您想要的任何-Xmx启动应用程序。
答案 5 :(得分:0)
以下blog中有关于如何使用jconsole和其他工具对java应用程序进行故障排除的完整博客文章。请记住,缺乏对内存使用的控制很可能是内存泄漏,但也可能是由于其他原因。看看帖子,试着复制那个场景,看看是否能解决你的问题。
http://www.kiragiannis.com/cloud-computing/debug-a-java-application-in-the-cloud/
答案 6 :(得分:0)
如果您还没有这样做,则需要通过内存分析器运行程序。您可能会发现某些数据结构没有被处理掉,即使它们已被不再使用。
JProfiler很漂亮,但你可以使用HPROF获得相同的信息,这是在Java 5中引入的:http://java.sun.com/developer/technicalArticles/Programming/HPROF.html
请记住,不同的平台具有不同的最大堆大小,基于体系结构(32位与64位),操作系统甚至JVM。
如果您有许多可以重复使用的值(例如您从XML文件中读取的字符串),则可以通过合并对象来大大降低内存需求。