当我在 Java 中定义像
var f = new float[1000][3][250][250];
这样的 4d 数组时,它只占用堆内存 797 MB。但是,当我将其定义为 var f = new float[1000][250][250][3];
时,根据 IntelliJ 分析器,它在堆上占用了 2273 MB(大约大 3 倍)。
有人可以解释一下原因吗?为什么维度排列对内存消耗影响这么大?
它不是应该占用大约 750 MB 的空间吗(1000×3×250×250×(4 字节浮点数)= 750)?
java中没有真正的多维数组的概念,这就是你犯错误的地方。 在Java中,new float[n][m]将被称为float类型数组的数组。简而言之,Java 不会像 C 或 C++ 那样为多维数组分配内存。
由于 Java 遵循 OOP 模式,数组也被视为对象,如果我们有一个数组作为
var arr = new float[2][3]
,我们也可以稍后更改 arr[0] = new float[5]
。在这种情况下,将数组数据存储在连续的内存位置中,确实会造成混乱。这就是为什么 Java 将其存储在堆中,在堆中分配的内存可以以数组的数组方式轻松缩小或扩大,其中较高维度存储下一个较低维度数组的引用。
现在,我认为内存的大小取决于 JVM 和机器架构。它如何存储数组引用、数据以及如何为多维数组缓存这些数据,会产生影响。
这里有更详细信息的参考 为什么Java没有真正的多维数组?