【问题标题】:Java class vs array memory size?Java类与数组内存大小?
【发布时间】:2023-03-31 05:53:01
【问题描述】:

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

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

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

class Node {
     public double x, y;
}

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

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

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

【问题讨论】:

    标签: java arrays class memory


    【解决方案1】:

    后者占用空间更小。

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

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

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

    【讨论】:

    • 目前在 Mac OS X 上以 x64 运行 Java 1.7 SE。现在我假设一个巨大的二维数组将完全消除每个节点所需的对象引用,因此这将是迄今为止最多的内存保守的方式?
    • 如果 2D 的意思是 double[2][n] 或 double[n][2],那也会导致对象引用。因为在这种情况下,java 中的数组是真正的数组数组
    • (您方式对此进行了过度优化,但是...)内存占用最少的是一维数组,您可以在其中显式计算索引。 Java 中的二维数组只是一个指向一维数组的指针数组。
    • 我建议你只创建一个长 id,double x,double y 的节点,使其通过 id 进行比较,然后在从数据库中读取它们时将它们插入树集中。
    • treeset 会给你 log(n) 但在这种情况下它应该足够了,因为 n 仍然相对较小并且操作很便宜。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

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

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

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

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

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

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

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

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

      【讨论】:

        猜你喜欢
        • 2013-05-19
        • 2017-11-10
        • 2016-01-05
        • 2013-04-12
        • 2011-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多