【发布时间】:2011-02-27 16:35:56
【问题描述】:
如果我有:
int c[] = new int[10];
和
int a[][] = new int[2][3];
一般来说
n*m*..*j 数组
如何在考虑引用变量的情况下计算实际内存使用量?
【问题讨论】:
-
获得这些数组的“实际内存使用情况”是否有动机?
如果我有:
int c[] = new int[10];
和
int a[][] = new int[2][3];
一般来说
n*m*..*j 数组
如何在考虑引用变量的情况下计算实际内存使用量?
【问题讨论】:
我知道我参加聚会有点晚了,但计算内存占用量真的不是特别难。
让我们举第一个例子:int c[] = new int[N];
根据 64 位内存模型,一个 int 是 4 个字节,所以所有元素的大小都是 4*N 字节。除此之外,Java 有 24 字节的数组开销,实际的数组对象也有 8 字节。所以总共是 32 + 4 * N 字节。
对于二维数组:int a[][] = new int[N][M];
基本相同,只是第一个数组中的每个元素都是另一个大小为 M 的数组,所以我们用 32 + 4 * M 代替 4,所以总大小是 32 + (32 + 4 * M) * N .
确实,D 维度的概括非常复杂,但你明白了。
【讨论】:
如果你想要一个准确的答案,你不能。至少不是以任何简单的方式。 This thread 解释更多。
Bragaadeesh 和 Bakkal 的答案的问题在于他们忽略了开销。每个数组还存储诸如维数、长度以及垃圾收集器使用的一些内容。
对于一个简单的估计,您应该可以使用其他答案的计算并添加 100-200 字节。
【讨论】:
您可能会从中得到最好的近似值:http://java.sun.com/javase/6/docs/api/java/lang/instrument/Instrumentation.html#getObjectSize(java.lang.Object)
这个article 和这个comprehensive one 演示/详细说明了这种方法
【讨论】:
int[] 或 int[][] 不是原始数据类型。它是Java中的一个对象。并且对于 Object,无法立即计算大小。
【讨论】:
+sizeof(int) 来自哪里?
sizeof(int) 会产生误导,即使在特定平台上它是 4 个字节。
我知道这是一个老问题,但我也有同样的问题,并且此线程中提供的信息对我没有帮助。给我所需信息的来源:https://www.javamex.com/tutorials/memory/array_memory_usage.shtml
这是我的情况:我有一个大数组
int a[][] = new int[m][n];
“大”实际上具有误导性:m 很大 (3^18 = 387420489) 但 n 很小 (4)。我一直遇到我不理解的内存问题,因为 m * n * 4 = 6198727824 (~6GB) 而我有 16GB 的 RAM(并且 JVM 允许使用 -Xmx12G 有 12 个)。我刚才放的链接给了我答案:
10 行中的每一行都有自己的 12 字节对象头,4*10=40 字节用于实际的整数行,同样,4 字节的填充使该行的总数达到 8 的倍数
这就是我的二维数组的内存明显偏离4 * m * n的地方:这里,因为n很小(4),所以每一行的大小确实不同于4 * n;如果你应用链接中给出的公式(即使它是近似的),你会得到,对于每一行:12(标题)+ 4 * 4(四个整数)+ 4(填充到 8 个字节的倍数)= 32。这是我预期成本的两倍,并说明我遇到了内存溢出。
【讨论】:
对于原始类型:字节的基本类型和大小
int a[M]:24+4M
(Class 16 + 保存数组大小 4 + 内存对齐 4) + (对于 double 的 M 大小,我们需要 4 * M)
int a[M][N]: (24+4M) + M*(24+4N) = 24+28M+4MN ~~~4MN
将 a[M][N] 视为 M 大小的双数组 a[N] 加上一个额外的数组来保存所有 M 大小数组起点的引用。
【讨论】:
M = ?,数组总是声明为int...这个答案可以改进。
Yann 上面的回答是正确的,我通过堆转储仔细检查了它。
这是我们计算数组的确切内存大小所需的数据(来源:https://www.javamex.com/tutorials/memory/array_memory_usage.shtml):
公式:
对于一个 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 字节
双[10][10] = [10 * (96 + 4) + 12] + [10 * (96 + 4) + 12] % 8 = 1016 字节
简单地乘以底层原始类型(错误)会产生:
双[10] = 8 * 10 = 80 字节
双[10][10] = 8 * 10 * 10 = 800 字节
【讨论】: