我必须在我的Java程序中存储数百万个X / Y双对以供参考。我想保持尽可能低的内存消耗以及对象引用的数量。所以在经过一番思考之后我决定将这两个点放在一个很小的双数组中可能是一个好主意,它的设置如下:
double[] node = new double[2];
node[0] = x;
node[1] = y;
我认为使用数组会阻止类与我在类中使用的X和Y变量之间的链接,如下所示:
class Node {
public double x, y;
}
然而,在阅读了类中公共字段的存储方式后,我突然意识到字段实际上可能不是像指针一样构造结构,也许JVM只是将这些值存储在连续的内存中并且知道如何在没有它们的情况下找到它们一个地址,从而使我的点的类表示小于数组。
所以问题是,内存占用量更小?为什么?
我对类字段是否使用指针特别感兴趣,因此具有32位开销。
答案 0 :(得分:5)
后者占地面积较小。
原始类型以内联方式存储在包含的类中。所以你的Node
需要一个对象标题和两个64位插槽。您指定的数组使用一个数组头(> =一个对象头),使用两个64位插槽。
如果您要以这种方式分配100个变量,那么它并不重要,因为它只是标题大小不同。
警告:所有这些都是有点推测的,因为你没有指定JVM - 其中一些细节可能因JVM而异。
答案 1 :(得分:0)
我不认为你最大的问题是存储数据,我认为它将会检索,编制索引并对其进行操作。
然而,从根本上说,阵列是要走的路。如果要保存指针,请使用一维数组。 (有人已经说过)。
答案 2 :(得分:0)
首先,必须说明实际的空间使用量取决于您使用的JVM。它严格针对具体实施。以下是典型的主流JVM。
所以问题是,内存占用量更小?为什么?
第二个版本较小。数组具有对象头中32位字段的开销,该字段保存数组的长度。对于非数组对象,大小隐含在类中,不需要单独表示。
但请注意,这是一个固定的头部每个数组对象。阵列越大,实际开销就越不重要。而使用类而不是数组的另一方面是索引不起作用,因此您的代码可能会更复杂(也更慢)。
Java 2D数组实际上是一维数组(等等)的数组,因此您可以将相同的分析应用于具有更高维度的数组。数组在任何维度上的大小越大,开销的影响就越小。 2x10
数组中的开销将小于10x2
数组中的开销。 (想一想......长度为10的长度为2 + 2的数组与 1长度为10 + 10的长度为2的数组。开销与数组的数量成正比。)
我对类字段是否使用指针特别感兴趣,因此具有32位开销。
(您实际上是在讨论实例字段,而不是类字段。这些字段不是static
...)
其类型为基本类型的字段直接存储在对象的堆节点中,而不进行任何引用。在这种情况下没有指针开销。
但是,如果字段类型是包装类型(例如Double
而不是double
),则可能存在引用的开销以及Double
的对象标头的开销对象