7

如果我创建 10 个整数和一个 10 的整数数组,占用的总空间会有什么不同吗?

我必须创建一个包含数百万条记录的布尔数组,所以我想了解数组本身将占用多少空间。

4

9 回答 9

6

整数数组表示为用于保存整数的内存块和对象头。对于 32 位 JVM,对象标头通常需要 3 个 32 位字,但这取决于平台。(标头包含一些标志位、对类描述符的引用、原始锁信息的空间以及实际数组的长度。加上填充。)

所以一个 10 个整数的数组可能会占用13 * 4字节区域。

在 an 的情况下Integer[],每个 Integer 对象都有一个 2 字标题和一个包含实际值的 1 字字段。您还需要添加填充和 1 个字(或 64 位 JVM 上的 1 到 2 个字)以供参考。这通常是数组的每个元素 5 个字或 20 个字节……除非某些 Integer 对象出现在数组中的多个位置。


笔记:

  1. 在 64 位 JVM 上实际用于引用的字数取决于是否使用“压缩 oops”。
  2. 在某些 JVM 上,堆节点以 16 字节的倍数分配……这会增加空间使用量(例如上面提到的填充)。
  3. 如果您获取一个对象的标识哈希码并且它在下一次垃圾回收中幸存下来,则它的大小会膨胀至少 4 个字节以缓存哈希码值。
  4. 除了上面列举的可变性来源之外,这些数字都是特定于版本和供应商的。
于 2012-07-13T08:17:56.993 回答
4

一些粗略的下界计算:

每个 int 占用四个字节。= 10 个 40 个字节

一个 int 数组为每个组件占用四个字节加上四个字节来存储长度加上另外四个字节来存储对它的引用。= 48 字节(+ 可能有一些填充以将所有对象对齐在 8 字节边界)

一个 Integer 至少占用 8 个字节,再加上另外 4 个字节来存储对它的引用。= 十个至少 120

一个整数数组至少占用十个整数的 120 个字节加上四个字节的长度,然后可能需要一些填充来对齐。加上四个字节来存储对它的引用。(@Marko 报告说他甚至测量了每个插槽大约 28 个字节,因此对于 10 个数组来说,这将是 280 个字节)。

于 2012-07-13T08:14:21.197 回答
2

在 java 中,你有 Integer 和 int。假设您指的是 int ,则 int 数组被认为是一个对象,并且对象具有元数据,因此 10 个 int 的数组将占用超过 10 个 int 变量

于 2012-07-13T08:13:21.900 回答
2

根据您的评论,如果您使用数组,则不会有太大的不同。Array 将为其功能本身使用可忽略不计的内存量。所有其他内存将由存储的对象使用。

编辑:您需要了解的是布尔包装器和布尔原始类型之间的区别。包装类型通常会比原语占用更多的空间。因此,对于记录任务,请尝试使用原语。

正如您所说,在处理记录任务时要记住的另一件事是Java Autoboxing。如果您无意中在遍历整个数组的函数中使用它,性能损失可能会很大。

于 2012-07-13T08:19:43.457 回答
1

你可以做的是测量

public static void main(String[] args) {
  final long startMem = measure();
  final boolean[] bs = new boolean[1000000];
  System.out.println(measure() - startMem);
  bs.hashCode();
}
private static long measure() {
  final Runtime rt = Runtime.getRuntime();
  rt.gc();
  try { Thread.sleep(20); } catch (InterruptedException e) {}
  rt.gc();
  return rt.totalMemory() - rt.freeMemory();
}

当然,这与标准免责声明是一致的:gc()没有特别的保证,所以重复几次,看看你是否得到一致的结果。在我的机器上,答案是每个boolean.

于 2012-07-13T08:27:35.177 回答
1

它不必对老师/面试官产生不良影响。

您对内存中变量的大小和对齐方式的关心程度取决于您需要代码的性能。例如,如果您的软件处理交易(EFT / 股票市场),这很重要。

变量在内存中的大小、对齐方式和打包可能会影响 CPU 缓存命中/未命中,这可能会影响代码的性能高达 100 倍。

只要您负责任地使用性能提升技巧,就知道在低级别发生了什么并不是一件坏事。

例如,我来到这个线程是因为我需要确切地知道这个问题的答案,以便我可以调整基元数组的大小以填充 CPU 缓存行的整数倍,因为我需要对这些数组执行计算的代码快速执行的原语,因为我有一个有限的窗口,我需要我的计算为结果的消费者做好准备。

于 2015-07-09T09:02:17.103 回答
0

在RAM空间方面,没有真正的区别

于 2012-07-13T08:12:21.697 回答
0

如果你使用一个数组,你有 11 个对象、10 个整数和数组,而且数组里面还有其他元数据。所以使用数组会占用更多的内存空间。

现在说真的。这种问题实际上出现在工作面试和考试中,这表明你有什么样的面试官或老师......在虚拟机和操作系统本身中有这么多抽象层,有什么意义在思考这个东西?微优化内存...!

于 2012-07-13T08:18:41.353 回答
0

我的意思是,如果我创建 10 个整数和 10 个整数数组,占用的总空间会有什么不同。

(integer array of 10) = (10 integers) + 1 integer

最后一个“+1 整数”用于数组的索引(数组可以容纳 2,147,483,647 的数据量,它是一个整数)。这意味着当你声明一个数组时,说:

int[] nums = new int[10];

您实际上从内存中保留了 11 个 int 空间。数组元素为 10,数组本身为 +1。

于 2012-07-13T08:30:05.270 回答