10

我必须在我的 Java 程序中存储数百万个 X/Y 双对以供参考。我想保持尽可能低的内存消耗以及对象引用的数量。因此,经过一番思考后,我决定将这两个点保存在一个很小的双数组中可能是个好主意,它的设置如下所示:

double[] node = new double[2];
node[0] = x;
node[1] = y;

我认为使用数组会阻止类与类中使用的 X 和 Y 变量之间的链接,如下所示:

class Node {
     public double x, y;
}

然而,在阅读了类中公共字段的存储方式之后,我突然意识到,字段实际上可能不是像指针一样的结构,也许 JVM 只是将这些值存储在连续的内存中,并且知道如何在没有地址的情况下找到它们使我的观点的类表示小于数组。

所以问题是,哪个内存占用更小?为什么?

我对类字段是否使用指针特别感兴趣,因此是否有 32 位开销。

4

3 回答 3

5

后者的占地面积更小。

原始类型内联存储在包含类中。因此,您Node需要一个对象标头和两个 64 位插槽。您指定的数组使用一个数组头(>= 一个对象头)加上两个 64 位插槽。

如果您要以这种方式分配 100 个变量,那么这并不重要,因为只是标题大小不同。

警告:所有这些都是推测性的,因为您没有指定 JVM - 其中一些细节可能因 JVM 而异。

于 2012-09-03T23:23:19.607 回答
0

我认为您最大的问题不是存储数据,而是检索、索引和操作数据。

但是,从根本上说,数组是要走的路。如果要保存指针,请使用一维数组。(有人已经说过了)。

于 2012-09-03T23:39:34.413 回答
0

首先,必须说明实际空间使用量取决于您使用的 JVM。它是严格执行特定的。以下是典型的主流JVM。

所以问题是,哪个内存占用更小?为什么?

第二个版本更小。数组具有对象头中保存数组长度的 32 位字段的开销。在非数组对象的情况下,大小在类中是隐含的,不需要单独表示。

但请注意,这是每个数组对象的固定开销。数组越大,实际开销就越不重要。使用类而不是数组的另一面是索引不起作用,因此您的代码可能会更复杂(并且更慢)。

Java 2D 数组实际上是 1D 数组(等等)的数组,因此您可以将相同的分析应用于具有更高维度的数组。数组在任何维度上的大小越大,开销的影响就越小。数组中的开销2x10将小于数组中的开销10x2。(考虑一下......长度为 2 的 1 个数组 + 长度为 10 的 2 个数组1 个长度为 10 的数组 + 长度为 2 的 10 个数组。开销与数组的数量成正比。)

我对类字段是否使用指针特别感兴趣,因此是否有 32 位开销。

(您实际上是在谈论实例字段,而不是类字段。这些字段不是static......)

类型为原始类型的字段直接存储在对象的堆节点中,无需任何引用。在这种情况下没有指针开销。

但是,如果字段类型是包装器类型(例如Double,而不是double),则可能存在引用的开销和对象的对象头的开销Double

于 2012-09-04T00:46:28.117 回答