9

我有一个执行 5 个不同任务的 java 程序。当我使用 -Xmx512m 内存参数运行程序时,任务 1-4 运行良好,但任务 5 内存不足。当我使用 -Xmx1024m 运行程序时,所有 5 个任务都运行良好,但以前使用 512m 堆运行良好的任务 1-4 现在几乎用完了所有 1024m 堆。如果我使用 -Xms128m -Xmx1024m,也会发生同样的事情。

指示 JVM 保持低内存利用率(例如,任务 1-4 为 512m)并且仅在实际需要时(例如,在任务 5 的情况下)使用更多内存的内存参数是什么?

也许我需要一种比默认设置更频繁地激活垃圾收集器的方法?

4

4 回答 4

10

这两个参数建议 jvm 在需要调整其堆大小时:

-XX:MaxHeapFreeRatio=10
-XX:MinHeapFreeRatio=10

这几乎意味着如果在 gc 之后,超过 10% 的堆是空闲的,它将尝试将内存还给操作系统。并且只有在 gc 之后使用超过 90% 的堆时才会增长堆。

这可能会减慢您的程序,因为 gc 将不断更改分配的内存大小。如果您的程序在短时间内分配大量内存,它可能根本没有效果。

于 2012-06-20T18:20:30.733 回答
5

我认为您对 JVM 的工作方式存在误解。这不是 GC 问题或“任务”问题。

您的任务存在内存泄漏,或者它们旨在占用越来越多的内存。

-Xmx1024m 设置 JVM 可以分配的最大内存。这就像你只有 1024 兆物理内存而没有虚拟内存一样。

使用 Task 的定义更新您的问题会很有帮助。这5个独立的JVM吗?或者在单个 JVM 中只有 5 个工作单元。

更新

我不打算让程序总是使用所有 1g 堆。我的意图是指示 JVM 在可以管理的情况下使用 512m 堆,并且仅在需要时使用更多内存。当内存不再需要时,回退到 512m 甚至更少的内存量。

仅仅因为您设置了 -Xmx1024m 并不意味着 JVM 将使用所有这些内存。这只是一个最大限制。设置 Xms 直到设置要使用的最小内存量。您的程序最终决定了正在使用的内存的运行量。如果它达到 -Xmx 设置的限制,那么它将抛出 OutOfMemoryError

您可以建议 JVM 通过调用来运行垃圾收集器System.gc()。注意我说的建议,你不能强制 GC 运行。你可以在一个甚至拒绝做 GC 的平台上运行。您还需要查看它为您的应用程序选择的 GC 算法。我会看这里Tuning Garbage Collector

如果您需要对内存使用进行如此精细的控制,您将需要选择除 JVM 之外的其他东西。

于 2012-06-20T15:51:28.073 回答
1

尝试使用http://visualvm.java.net/以查看内存消耗。然后您可以使用 jhat 来可视化堆内容并使用http://www.eclipse.org/mat/来识别泄漏。

于 2012-06-20T16:10:24.377 回答
1

通过将 -Xmx1024m 传递给虚拟机,您基本上可以告诉虚拟机它最多可以使用 1 gig 的堆,它最终会这样做。VM 在需要时开始运行垃圾收集,例如。当堆用完时,这取决于可用的堆大小。如果您知道要在外部运行哪个任务(我猜您这样做是因为您将它作为 cmd 行参数传递),为什么不从外部也设置 -Xmx 呢?

于 2012-06-20T16:03:18.817 回答