我正在學習和測試一些圖庫,並遇到一個奇怪的問題(但這不是特定於圖形,我非常確定這是一般的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