Java中的内存方面的数组与矩阵

时间:2015-01-22 07:09:14

标签: java c arrays matrix

我正在开发一个涉及启发式的项目,我用Java构建它(应该可能在C中创建)。 我遇到了记忆问题。

我的树是用对象节点构建的,每个对象包含一个数组,一个矩阵和三个整数。 我已经减少了许多其他值,为了尝试节省更多的内存空间,但是,它仍然是不够的。

所以,我想我也可以减少矩阵,并将其转换为数组。 但是,我的整个项目建立在坐标上,以达到矩阵中的某个点。 所以在我做出任何改变之前,我想知道这会对内存使用产生多大影响(或不太多)。

编辑:数组和矩阵都由int基元组成。

数组是数组[25],矩阵是矩阵[5] [5]。

矩阵代表游戏的棋盘,包含该字段是否为空,或者其中是否有某种类型的片段(全部为int)的信息。

我说的是16GB的RAM使用量和2500万个节点。

我制作了这个方法来克隆数组:

public int[] cloneArray(int[] array){
    int i = 0;
    int[] clone = new int[array.length];
    while (i < array.length){
        clone[i] = array[i];
        i++;
    }
    return clone;
}

类似的方法,克隆矩阵和对象本身。

编辑: 在发现了一个分析器的存在后,我做了一个检查。 以下是结果的屏幕截图: Java profiler stats

我认为这些数字是有意义的,因为在控制台中,您可以看到几乎同样数量的节点,正如您在分析器中看到的那样,状态(在控制台中,“estados”是状态的指针目前正在扩大)。

因此,在分析器中,我们可以看到近20m的状态,即生成的节点。 每个州包含1个数组和1个矩阵。

我们可以看到138米阵列,除以6等于23米。 由于矩阵是5x5,因此矩阵中包含5x23m的数组,而另外23m是数组。

我有道理吗?这种解释准确吗?

这是一个保管箱链接,因此您可以查看完整分辨率图片: https://www.dropbox.com/s/7wxz8vch1wnrsyr/Untitled.png?dl=0

2 个答案:

答案 0 :(得分:1)

你的问题可能暗示你的代码中存在隐藏的问题而不是“内存不足问题”。堆内存没有那么快完成,你需要你的代码非常繁重才能到达那里。

仍然,我敢说将2维矩阵更改为数组不会改变内存使用量。 说到哪 - 实现高维数组(2及以上)的两种最常见的方法是1)将其切片到一维数组,然后使用公式:

arr[a][b].. = arr[a+b+..]

2)使用指针指针,然后你得到一个指针数组,指向另一个指针数组,依此类推,直到最后一级为真实对象

这说,(再次,敢于说),Java可能已经将矩阵切片为幕后的一维数组。

无论如何,我强烈怀疑你的代码中存在内存泄漏,或者没有结束递归,或者是上述的组合。在尝试实施你的建议之前,试着看你不在那里。

答案 1 :(得分:1)

以下是几个例子:

int[] array = new int[25];

int[][] matrix = new int[5][5];

数组占用的空间是:

  • 25 x 4字节整数(数组内容)
  • 数组的12个字节的对象标题
  • 总共112个字节

Java中的2D int矩阵实际上是一个数组数组,因此矩阵占用的空间是

  • (5 x 4字节整数+ 12字节数组标题)x 5.
  • 5 x 4字节引用+ 12字节的数组头
  • 总共192个字节

(上面假设是一个32位的JVM,以及典型的数组头大小。这些是特定于平台的假设,但是对于任何JVM平台,你应该能够将它们与特异性联系起来。对于Oracle自Java 6以来的HotSpot / OpenJDK JVM,源代码可供任何人查看。)

当然请注意,随着数组/矩阵越来越大,int[N^2]int[N][N]的相对保存会变小。