如何计算java数组内存的使用情况

时间:2010-06-04 08:37:25

标签: java arrays

如果我有:

int c[] = new int[10];

int a[][] = new int[2][3];

一般

n*m*..*j数组

如何考虑引用变量来计算实际内存使用量?

7 个答案:

答案 0 :(得分:15)

如果你想要一个准确的答案,你不能。至少没有任何简单的方法。 This thread解释了更多。

Bragaadeesh和Bakkal答案的麻烦在于它们忽略了开销。每个数组还存储诸如它具有的维数,它有多长以及垃圾收集器使用的一些东西之类的东西。

对于一个简单的估计,你可以使用其他答案的计算并添加100-200个字节。

答案 1 :(得分:12)

我知道我有点迟到了,但计算内存占用并不是非常困难。

让我们举个例子:int c[] = new int[N];

根据64位内存模型,int是4个字节,因此所有元素的大小都是4 * N字节。除此之外,Java具有24字节的数组开销,并且实际的数组对象也有8个字节。所以这总共是32 + 4 * N字节。

对于二维数组:int a[][] = new int[N][M];

基本上相同的是,第一个数组中的每个元素都是另一个大小为M的数组,所以不是4个,而是32 + 4 * M,所以总大小为32 +(32 + 4 * M)* N

D维的推广确实非常复杂,但你明白了。

答案 2 :(得分:1)

int[]int[][]不是原始数据类型。它是Java中的Object。使用Object,无法立即计算大小。

答案 3 :(得分:1)

答案 4 :(得分:0)

我知道这是一个老问题,但是我有一个相同的问题,并且该线程中提供的信息对我没有帮助。给我提供所需信息的资源:https://www.javamex.com/tutorials/memory/array_memory_usage.shtml

这是我的情况:我的阵列很大

+---+-----+------------------------+
|ID |Count|percentile              |
+---+-----+------------------------+
|1  |10.0 |[10.0, 15.6, 20.0, 39.6]|
|1  |20.0 |[10.0, 15.6, 20.0, 39.6]|
|1  |40.6 |[10.0, 15.6, 20.0, 39.6]|
|1  |15.6 |[10.0, 15.6, 20.0, 39.6]|
|1  |17.6 |[10.0, 15.6, 20.0, 39.6]|
|1  |25.6 |[10.0, 15.6, 20.0, 39.6]|
|1  |39.6 |[10.0, 15.6, 20.0, 39.6]|
|3  |60.6 |[60.6, 60.6]            |
|3  |80.6 |[60.6, 60.6]            |
|4  |30.6 |[30.6, 30.6]            |
|4  |90.6 |[30.6, 30.6]            |
|2  |20.5 |[20.5, 45.4, 70.3]      |
|2  |70.3 |[20.5, 45.4, 70.3]      |
|2  |69.4 |[20.5, 45.4, 70.3]      |
|2  |74.4 |[20.5, 45.4, 70.3]      |
|2  |45.4 |[20.5, 45.4, 70.3]      |
+---+-----+------------------------+

其中“大”实际上是令人误解的:m大(3 ^ 18 = 387420489),而n小(4)。我一直遇到我不了解的内存问题,因为m * n * 4 = 6198727824(〜6GB)而我却有16GB的RAM(以及-Xmx12G允许12个JVM)。我刚刚输入的链接给了我答案:

10行中的每行都有其自己的12字节对象标头,实际int行的4 * 10 = 40字节,再加上4字节的填充,使该行的总数为8的倍数< / p>

这是我的二维数组的内存实质上偏离4 * m * n的地方:在这里,因为n小(4),所以每行的大小实际上与4 * n不同;如果应用链接中给出的公式(即使是近似值),则每一行的结果为:12(标题)+ 4 * 4(四个整数)+ 4(填充为8字节的倍数)= 32。这是我预期的两倍,并说明我遇到内存溢出。

答案 5 :(得分:0)

Yann 上面的回答是正确的,我通过堆转储对其进行了仔细检查。

这是我们计算数组确切内存大小所需的数据(来源:https://www.javamex.com/tutorials/memory/array_memory_usage.shtml):

  • Java 选择的类型大小(例如:double = 8 字节)'S'
  • Java 数组四舍五入为:8 字节“q”的倍数
  • Java 参考大小:4 字节 'R'
  • Java 数组头大小:12 字节 'H'

论坛:

对于 double[N] = (N * S + H) + (N * S + H) % q = 'x'

对于双精度[M][N] = [M * (x + R) + H] + [M * (x + R) + H] % q = 'y'

举个例子:

double[10] = (10 * 8 + 12) + (10 * 8 + 12) % 8 = 96 字节

double[10][10] = [10 * (96 + 4) + 12] + [10 * (96 + 4) + 12] % 8 = 1016 字节

简单地乘以底层原始类型(错误)会产生收益:

double[10] = 8 * 10 = 80 字节

double[10][10] = 8 * 10 * 10 = 800 字节

答案 6 :(得分:-1)

原始类型:字节的基本类型和大小

  • 布尔1
  • byte 1
  • char 1
  • int 4
  • float 4
  • 长8
  • double 8
  • Interger 24(Class实例为16 + int为4 +内存对齐为4)

int a [M]:24 + 4M

(16为Class + 4为保存数组大小+ 4为内存对齐)+(对于M大小为double,我们需要4 * M)

int a [M] [N] :( 24 + 4M)+ M *(24 + 4N)= 24 + 28M + 4MN ~~~ 4MN

将[M] [N]视为双数组的M大小a [N]加上一个额外数组以保存所有M大小数组起始点的引用。