当前位置: 首页 > 知识库问答 >
问题:

Java类vs数组内存大小?

梁马鲁
2023-03-14

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

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

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

class Node {
     public double x, y;
}

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

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

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

共有3个答案

束新
2023-03-14

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

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

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

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

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

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

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

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

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

钱朝明
2023-03-14

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

然而,从根本上来说,数组是一种可行的方法。如果你想节省指针,使用一维数组。(已经有人说过了)。

贲宜春
2023-03-14

后者的占地面积较小。

基元类型以内联方式存储在包含类中。因此,您的节点需要一个对象标头和两个 64 位插槽。您指定的数组使用一个数组标头 (

如果你打算以这种方式分配100个变量,那么这没什么大不了的,因为只是头的大小不同而已。

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

 类似资料:
  • 问题内容: 我热衷于研究Scala,并提出了一个似乎无法找到答案的基本问题:一般来说,Scala和Java在性能和内存使用方面是否有所不同? 问题答案: Scala使得无需意识到即可轻松使用大量内存。这通常非常强大,但有时可能很烦人。例如,假设您有一个字符串数组(称为),以及从这些字符串到文件的映射(称为)。假设您要获取地图中所有来自长度大于两个的字符串的文件。在Java中,您可能 ew!辛苦了

  • 我正在运行一个java应用程序,我观察到如下情况: 通过代码我正在计算内存利用率: 时间戳S0 S1 E O P YGC YGCT FGC FGCT GCT 2849.6 0.00 84.80 93.14 16.95 60.00 483 140.140 8 3.649 143.789 首先,我的代码将显示哪个内存。老人、伊甸园或幸存者。我觉得老了。。m i rgt?? 在特定的时候,我观察到我的代

  • 有人能给我解释一下上面这一行的记忆地图吗。它将有多少个对象和引用?

  • 我正在构建一个Spark应用程序,我必须在其中缓存大约15GB的CSV文件。我在这里读到了Spark 1.6中引入的新: https://0x0fff.com/spark-memory-management/ 作者在和之间有所不同(火花内存又分为)。正如我所了解的,Spark内存对于执行(洗牌、排序等)和存储(缓存)东西是灵活的——如果一个需要更多内存,它可以从另一个部分使用它(如果尚未完全使用)

  • 上面链接中的代码正在工作,但可以传输到一定数量的数据。当我试图传输一个大小约为334 MB的.mkv格式的电影时,它给出了“内存不足,java堆大小”的错误。我是一个乞丐,我不知道如何解决这个问题,我试图在客户端程序中增加缓冲区大小,但问题仍然存在。请帮帮我.

  • 我在一个docker容器中的Java8上运行了一个java应用程序。该过程启动Jetty9服务器,并部署web应用程序。传递以下JVM选项:。 最近我注意到该过程消耗了大量内存: