异常Java堆空间

时间:2018-11-10 09:38:30

标签: java

这是我的代码:

public static void runSGD(double[] R, double[][] theta, double convergenceTol)
{
    List<Integer> allEdges = new ArrayList<Integer>(2*E);    
    for (int i = 0; i < 2*E; i++) 
        allEdges.add(i);
    Collections.shuffle(allEdges, new Random(shuffleSeed));
    double oldRes = calcObj(R, theta, allEdges), newRes = 0.0;
    long numEdges = 0;
    for (int _e = 0; _e < 2*E*tp; _e++) {
        int e = allEdges.get(_e);
        numEdges += weights.get(e);
    }
    if (verbose)
        System.out.printf("[Info] Number of edges in training, including multiplicity = %d\n", numEdges);
    int[][] edgeTable = new int[4][1<<30];
    long part = 0; int cur = 0;
    for (long i = 0; i < numEdges; i++) {
        if (i+1 > part) {
            part += weights.get(allEdges.get(cur));
            cur++;
        }
        int row = (int) (i >>> 30);
        int col = (int) (i & ((1 << 30) -1));
        edgeTable[row][col] = allEdges.get(cur-1);
    }
}

运行以下代码时错误为Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

 int[][] edgeTable = new int[4][1<<30];

我尝试了-Xmx1g,-Xmx3g,但是没有用,如何解决?

3 个答案:

答案 0 :(得分:2)

您要分配2个30个整数的4个int[]数组。那是2 ^ 34字节或16 GB。显然,这不适合1或3 GB的堆。确实,典型的笔记本电脑或PC将没有足够的RAM用于此操作...

关于堆空间是否足够大以容纳2 ^ 32字节对象还有一个次要问题,但是如果可以使堆足够大,应该可以解决这个问题。

事实上,JVM支持2 ^ 31个以下元素的数组;参见Do Java arrays have a maximum size?,因此数组大小本身并不是这里的问题。

答案 1 :(得分:0)

数组使用整数来寻址单个数组元素。最大int值为2 ^ 31-1。 您创建4个大小为2 ^ 30的数组,这意味着您的数组中有2 ^ 32个元素。 Java简单地不支持该大小的数组。

您可以通过制作4个不同的数组来修复它。

用-Xmx3g分配3GB也无济于事,因为仅您的阵列就需要16GB的RAM。

答案 2 :(得分:0)

正如其他人提到的那样,您正在尝试分配巨大的数组。您可以尝试分配小数组的块或尝试集合。