这是我的代码:
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,但是没有用,如何解决?
答案 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)
正如其他人提到的那样,您正在尝试分配巨大的数组。您可以尝试分配小数组的块或尝试集合。