Java中使用ArrayList<List<Integer>>出现OutOfMemoryError错误

3
我希望在Java中创建一个非常大的图(大约有1000万个边)。我计划使用List<List<Integer>>来描述边,其中内部List<Integer>描述每条边的两个顶点(顶点类型是整数)。
当向图添加了约100万条边后,以下代码会抛出OutOfMemoryError异常。(出于讨论的简洁,我简化了如何生成边的过程。)
public static void main(String[] args) {
  List<List<Integer>> graph = new ArrayList<List<Integer>>();
  for (int i = 0; i < 10000000; i++) {
    List<Integer> edge = new ArrayList<Integer>();
    // the real edges are more complicated (than from vertex i to vertex i+1)
    // this is simplified for the sake of the discussion here
    edge.add(i);
    edge.add(i+1);
    graph.add(edge);
  }
}

我搜索了OutOfMemoryError,并将Eclipse的初始堆大小增加到2G:-Xms2g -Xmx4g -Xss2m(传递给JVM)。但这并没有解决问题。

然后我想也许我应该垃圾回收List<Integer> edge变量,通过调用System.gc(),以防其内存未被清除。但这也没有起作用。

我在想问题可能出在List<List<Integer>>数据结构上。我尝试使用List<int[]>,持续时间更长:在发生OutOfMemoryError之前添加了更多的边缘。我现在没有更好的想法。

我搜索了类似的问题,但没有找到太多帮助。我想知道是否有人遇到过这种情况。


创建一个只有两个整型字段的边缘类怎么样? - JaskeyLam
3
您设置Eclipse的参数不会传递给程序内部。 - SwiftMango
请检查Eclipse启动配置,参数选项卡,VM参数文本框;在那里使用适当的-Xmx参数。可能您的jvm正在以默认限制启动,通常为256MB。此外,请查看您的帖子中小于和大于字符的情况,因为它看起来肯定不正确。 - chrisinmtown
@chrislott,感谢您对运行配置中VM参数的评论。我认为您所说的“小于号和大于号字符”是指泛型中的尖括号? - Ethan
2个回答

5
为了让您的程序在Eclipse中使用更多内存:
1. 转到“Run -> Run Configurations”选项。您将看到此窗口 Run Configurations 2. 点击“Arguments” Run Configurations/Arguments 3. 输入VM参数 Run Configurations/Arguments/VM Arguments

0

由于您使用了大量的RAM,除了设置最大堆参数之外,请确保使用64位的Java。32位的版本限制在2G或类似的数值。

另外,对于大型图形,您应该考虑使用数据库。

最后但并非最不重要的是,也许您可以重新思考一下算法,有时候您并不需要所有的节点和边。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接