【发布时间】:2012-03-29 14:49:47
【问题描述】:
我正在学习和测试一些图形库并且遇到了一个奇怪的问题(但这不是特定于图形的,我很确定这是一般的 Java 相关的)。我得到:'java.lang.OutOfMemoryError:超过 GC 开销限制'。 I understand this error means that garbage collecting spending most of the cpu time and not returning any memory 但我不知道如何解决这个问题。
基本上我(出于学习目的)想看看在内存中创建大量图形节点需要多长时间。我的系统正在运行美分,我有 7 gigs 的 ram,但程序从未超过 25%(我可以通过“顶部”看到),即使我通过运行“java -jar jungtester”将系统中的所有内存都给了它.jar -Xmx7g -XX:+UseConcMarkSweepGC -XX:-UseGCOverheadLimit'(jungtester.jar 是我的程序)。似乎它没有使用所有可用内存并在大约 350 万个节点后死亡,这很奇怪,因为它只是一个 for 循环,所以我认为它只是在添加节点之前一直在不停地添加节点,直到内存已满。
我对 JVM 的内部工作很陌生,所以任何关于如何克服这个问题的建议都会很棒。
如果有帮助,代码如下:
import edu.uci.ics.jung.graph.DirectedGraph;
import edu.uci.ics.jung.graph.DirectedSparseGraph;
public class main {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("starting...");
long startTime = System.currentTimeMillis();
DirectedGraph<Integer,Integer> graph = new DirectedSparseGraph<Integer, Integer>();;
graph.addVertex(1);
graph.addVertex(2);
graph.addEdge(1, 1,2);
for (int i = 0; i < 1000000; i++) {
graph.addVertex(i);
//System.out.println(i + " means we are " + (float) i/1000000 + "% done.");
}
long endTime1 = System.currentTimeMillis();
System.out.println("done adding 1000000 in " + (endTime1 - startTime));
for (int i = 1000001; i < 10000000; i++) {
graph.addVertex(i);
graph.addEdge(i, i, i-1000000);
System.out.println(i + " means we are " + (float) i/1000000000 + "% done.");
}
long endTime = System.currentTimeMillis();
System.out.println("It took " + (endTime - startTime));
}
}
更新:我让它工作了,我不知道为什么,但顺序很重要。我上面的命令在我放 -jar 之后没有采取任何措施,但是当我将 -jar 添加到末尾时,它似乎可以工作。
【问题讨论】:
-
使用 jconsole(如果你有 X 可用)在你的应用程序运行时监控 JVM,它会告诉你发生了什么。 Top 在向您显示 JVM 实时统计数据方面几乎没有 jconsole 那样精细。
-
您是在 32 位还是 64 位机器上运行它? 32 位系统无法使用 7G 内存。
-
@PéterTörök - 没错,但如果您在 32 位机器上使用
-Xmx7g,JVM 将不会启动。所以我认为这不是问题。 -
抱歉,我在命令行上运行它(我没有可用的图形)@PéterTörök 它是 64 位机器。
-
@learningJava 是 64 位 JVM 吗?
标签: java