我正在学习和测试一些图库,并遇到一个奇怪的问题(但这不是特定于图形,我非常确定这是一般的Java相关)。我得到:'java.lang.OutOfMemoryError:超出GC开销限制'。 I understand this error means that garbage collecting spending most of the cpu time and not returning any memory但我不确定如何解决此问题。为什么我得到'java.lang.OutOfMemoryError:超出GC开销限制',如果我有大量的可用内存给JVM?
基本上我(为了学习目的)想看看在内存中创建大量图节点需要多长时间。我的系统运行的是美分,我有7个ram的演出,但是程序从未超过25%(我可以通过'top'看到),即使我通过运行'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并没有像Jconsole那样显示JVM实时统计数据。 – robertvoliva 2012-03-29 14:53:44
你是在32位还是64位机器上运行它? 32位系统无法使用7G的RAM。 – 2012-03-29 14:54:11
@PéterTörök - 确实如此,但是如果在32位机器上使用'-Xmx7g',则JVM将无法启动。所以我不认为这是问题。 – 2012-03-29 15:00:57