问题在于Java并没有真正的多维数组。一个四维数组实际上是数组的数组(即数组的数组的数组的数组),因此最内层数组的大小至关重要。
对于代码 var f = new float[1000][3][250][250];
需要有10003250(即75万个)个 float[250]
类型的数组。使用jol工具计算得知,一个 float[250]
数组占用1016字节,因此最内层数组总共需要75万个*1016字节,即750MB。
加上中间层数组的大小(共有75万个中间层数组),总计约为796MB,这与你观察到的结果相符。
而对于 var f = new float[1000][250][250][3];
则需要1000250250(即6250万个)个 float[3]
类型的数组。再次使用jol计算,得知一个 float[3]
数组占用32字节,因此仅最内层就需要6250万个*32字节,即2000MB。加上中间层数组的大小(共有6250万个中间层数组),总和约为2276MB,与你的观察一致。
需要注意的是,由于对齐限制和数组开销,一个 float[3]
即便只有3个浮点数,也需要32字节,相当于每个浮点元素占用约10字节!而一个 float[250]
则需要1016字节,略高于浮点数实际所需的4字节。