如何计算java阵列内存使用率

如何计算java阵列内存使用率,java,arrays,Java,Arrays,如果我有: int c[] = new int[10]; 及 大体上 一个n*m*.j数组 考虑到引用变量,如何计算实际内存使用量?int[]或int[][]不是原始数据类型。它是Java中的一个对象。对于一个物体,它的大小不能马上计算出来。如果你想要一个准确的答案,你就不能。至少不容易。解释得更多 Bragaadeesh和Bakkal的答案的问题在于他们忽略了开销。每个数组还存储诸如它的维数、长度以及垃圾收集器使用的一些内容 对于一个简单的估计,您可以使用其他答案的计算结果并添加100-20

如果我有:

int c[] = new int[10];

大体上

一个
n*m*.j
数组


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

int[]
int[][]
不是原始数据类型。它是Java中的一个对象。对于一个物体,它的大小不能马上计算出来。

如果你想要一个准确的答案,你就不能。至少不容易。解释得更多

Bragaadeesh和Bakkal的答案的问题在于他们忽略了开销。每个数组还存储诸如它的维数、长度以及垃圾收集器使用的一些内容


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

您可能会从以下公式中获得最佳近似值:


这个,这个演示/详细说明了这个方法

我知道我参加聚会有点晚了,但是计算内存占用并不是很难

让我们来看第一个例子:
intc[]=newint[N]

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

对于二维数组:
inta[][]=newint[N][M]

基本上是一样的,第一个数组中的每个元素都是另一个大小为M的数组,所以我们用32+4*M代替了4,所以总大小是32+(32+4*M)*N


的确,D维的泛化非常复杂,但你知道了。原始类型:基类型和字节大小

  • 布尔1
  • 字节1
  • 字符1
  • int 4
  • 浮动4
  • 长8
  • 双8
  • 整数24(16表示类实例+4表示int+4表示内存对齐)
inta[M]:24+4M

(16类+4用于保存数组大小+4用于内存对齐)+(对于双精度的M大小,我们需要4*M)

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


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

我知道这是一个老问题,但我也有同样的问题,这篇文章中给出的信息对我没有帮助。提供我所需信息的来源:

我的情况是:我有一个大数组

int a[][] = new int[m][n];
其中“大”实际上是误导性的:m是大的(3^18=387420489),但n是小的(4)。我一直遇到我不理解的内存问题,因为m*n*4=6198727824(~6GB),而我有16GB的RAM(允许使用-Xmx12G的JVM使用12个)。我刚才的链接给了我答案:

这10行中的每一行都有自己的12字节对象头,4*10=40字节表示实际的整数行,4字节的填充使该行的总数达到8的倍数


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

Yann上面的回答是正确的,我通过堆转储再次检查了它

以下是计算数组的确切内存大小所需的数据(来源:):

  • Java选定类型大小(例如:双字节=8字节)'S'
  • Java数组四舍五入到:8字节'q'的倍数
  • Java引用大小:4字节'R'
  • Java数组头大小:12字节'H'
Forumulas:

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

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

例如:

双精度[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字节


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

什么是
+sizeof(int)
的来源?根据您的平台,引用可能不是4字节。@Matti:同意。整件事都不对。让我来编辑它。将引用内存写入
sizeof(int)
是一种误导,即使在特定的平台上是4字节。我认为如果我们继续编辑以使其在技术上正确,我们将解决“没有简单准确的方法”:p这个答案是正确的。由于类型/GC信息和诸如此类的原因,总是存在开销。另外,Java没有真正的多维数组,只有交错数组,这最终会产生相当大的开销。多维数组在内存中是如何表示的?我删除了我的答案,因为我不知道如何计算包含开销的确切大小。@xdevel2000:Java没有多维数组。只有数组的数组。@Matti Virkkunen:True。VM仍然跟踪嵌套了多少层数组,因此您不能将一个字符数组分配给一个字符数组。获取这些数组的“实际内存使用率”背后有什么动机吗?从哪里获得24字节的开销?我想这个数字是针对某个特定的虚拟机的。这就是我需要的答案。我正在做一个项目,我需要一个相当大的阵列,我不想把它分解成一堆磁盘操作,我需要知道这些对象将消耗多少内存。谢谢。当您讨论不同的类型时,我们可能会有不同的大小,但对于int,我们可以进行计算(可能会有一些差距,因为备忘录)
int a[][] = new int[m][n];