简体   繁体   English

就Java中的内存而言,数组与矩阵

[英]Array vs Matrix in terms of memory in Java

I am working on a project that involves heuristics, and I built it in Java (Should have probably made it in C). 我正在一个涉及启发式的项目中,我用Java构建了它(可能应该在C中实现)。 I am running into problems with memory. 我遇到内存问题。

My tree is built up with object nodes, and each object contains an array, a matrix, and three integers. 我的树由对象节点组成,每个对象包含一个数组,一个矩阵和三个整数。 I already cut down many other values, in order to try and save more memory space, however, it still isn't enough. 我已经削减了许多其他值,以尝试节省更多的内存空间,但是,这还不够。

So, I was thinking that I could also cut down the matrix, and transform it into an array. 因此,我当时想我也可以缩减矩阵并将其转换为数组。 However, my whole project is built on coordinates, to reach a certain point in the matrix. 但是,我的整个项目都建立在坐标上,以到达矩阵中的某个点。 So before I make any change, I would like to know how much (or not so much) this would affect memory usage. 因此,在进行任何更改之前,我想知道这将影响内存使用量的多少(或没有那么多)。

Edit: The array and matrix both are made of int primitives. 编辑:数组和矩阵都由int原语组成。

The array is array[25] and the matrix is matrix[5][5]. 数组为array [25],矩阵为matrix [5] [5]。

The matrix represents the board of the game, with information of whether the field is empty, or has a certain type of piece inside it (all int). 矩阵表示游戏的棋盘,其中包含有关该字段是空还是内部有某种棋子的信息(全部为int)。

I am talking about 16GB of RAM usage, and 25 million nodes. 我说的是16GB的RAM使用情况和2500万个节点。

I made this method, to clone arrays: 我做了这个方法,克隆数组:

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;
}

Similar methods were made, to clone matrixes, and the objects themselves. 采取了类似的方法来克隆矩阵和对象本身。

Edit: After finding out about the existence of a profiler, I made a check. 编辑:在发现存在探查器后,我进行了检查。 Here is a screenshot of the results: 这是结果的屏幕截图: Java Profiler统计信息

I think these numbers make sense, because in the console, you can see nearly as many nodes that were counted, as you can see in the profiler, the states (in the console, "estados" is the pointer of the state that is currently being expanded). 我认为这些数字是有道理的,因为在控制台中,您可以看到计数的节点数量几乎与在探查器中看到的状态数量一样(在控制台中,“ estados”是当前状态的指针)正在扩展)。

So, in the profiler, we can see almost 20m states, which are the generated nodes. 因此,在事件探查器中,我们可以看到几乎20m个状态,即所生成的节点。 Each state contains 1 array and 1 matrix. 每个状态包含1个数组和1个矩阵。

We can see 138m arrays, which divided by 6 equals 23m. 我们可以看到138m个数组,除以6等于23m。 And since a matrix is 5x5, then 5x23m of the arrays are contained in the matrix, and the other 23m are the arrays. 并且由于矩阵为5x5,因此矩阵中包含5x23m的阵列,其他23m为阵列。

Am I making sense? 我说得通吗 Is this interpretation accurate? 这种解释正确吗?

Here is a dropbox link, so you can check the full resolution image: https://www.dropbox.com/s/7wxz8vch1wnrsyr/Untitled.png?dl=0 这是一个保管箱链接,因此您可以查看完整分辨率的图像: https : //www.dropbox.com/s/7wxz8vch1wnrsyr/Untitled.png?dl=0

Your question may suggest hidden problem in your code rather then "out of memory problem". 您的问题可能暗示代码中存在隐藏问题,而不是“内存不足问题”。 the heap memory is not finish so fast , you need your code to be extremely heavy in order to get there. 堆内存没有那么快完成,您需要代码非常繁重才能到达那里。

still, I'll dare to say that changing 2 dimensional matrix into an array wouldn't change the memory usage much. 我仍然敢说将二维矩阵更改为数组不会显着改变内存使用率。 speaking on which - the 2 most common ways to implement higher-dimensions arrays (2 and above) are 1) slice it to one dimension array, then use the formula : 讲哪种-实现高维数组(2及以上)的2种最常见方法是1)将其切成一维数组,然后使用公式:

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

2) use pointers to pointers , then you get an array of pointers , which points to another array of pointers and so on until the final level which are real objects 2)使用指向指针的指针,然后得到一个指针数组,该指针指向另一个指针数组,依此类推,直到最后一级都是真实对象

this said , (again , with dare) , Java may already slice the matrix into one dimension array behind the scenes. 这就是说(再次,敢于),Java可能已经在幕后将矩阵切成一维数组。

any way , I highly suspect you have memory leak in your code , or not-ending-recursion, or a combination of the above . 无论如何,我高度怀疑您的代码中存在内存泄漏,或者not-end-递归,或者以上两种情况的组合。 try to see you're not there before trying to implement what you suggested. 在尝试实施建议的内容之前,请先查看您是否不在。

Here are a couple of examples: 以下是几个示例:

int[] array = new int[25];

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

The space occupied by the array is: 数组占用的空间为:

  • 25 x 4 byte ints (the array contents) 25 x 4字节整数(数组内容)
  • 12 bytes of object header for the array 数组对象标头的12个字节
  • total 112 bytes 总共112个字节

A 2D int matrix in Java is actually an array of arrays, so the space occupied by the matrix is Java中的2D int矩阵实际上是一个数组数组,因此该矩阵占用的空间为

  • (5 x 4 byte ints + 12 bytes of array header) x 5. (5 x 4字节int + 12字节的数组头)x 5。
  • 5 x 4 byte references + 12 bytes of array header 5 x 4字节引用+ 12字节数组头
  • total 192 bytes 总共192个字节

(The above assumes a 32 bit JVM, and typical array header sizes. Those are platform specific assumptions, but for any JVM platform you should be able to tie them down with specificity. And for Oracle HotSpot / OpenJDK JVMs since Java 6, the source code is available for anyone to see.) (以上假定了32位JVM和典型的数组头大小。这些是特定于平台的假设,但是对于任何JVM平台,您都应该能够将它们与特定性联系在一起。对于自Java 6以来的Oracle HotSpot / OpenJDK JVM,源代码代码可供任何人查看。)

Note of course that as the arrays / matrices get larger, the relative saving for an int[N^2] versus an int[N][N] becomes smaller. 当然,请注意,随着数组/矩阵变大,与int[N][N]相比, int[N][N] int[N^2]的相对节省变得更小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM