一个较大的变量比其他几个变量消耗更多的内存,即使较小变量的总和等于较大变量的大小?

A single bigger variable consumes more memory than few other variables, even though the sum of the smaller ones are equal to the size of the bigger?

假设我们 'a' 持有一个包含 N 个值的列表。我们还有 'b'、'c' 和 'd',其中它们的总和也持有 N.

在内存消耗方面'a'比'b + c + d'消耗的总和还要多?

谁能说?容量!=大小。但在其他条件相同的情况下,3 个单独的 ArrayList 比一个 ArrayList 占用更多的内存,因为列表结构本身需要 space 除了它包含的内容。

我特别为这个例子调出了 ArrayList,因为它在概念上很简单。毫无疑问,人们可以发明实现 List 接口的结构,反之亦然:即,内存使用量的增长速度快于它所包含的速度。

不过你的术语是错误的。每个参考变量(a、b、c、d)的大小完全相同:一个参考。是引用的对象有不同的大小。

ArrayList 是一个 class,它包含一个支持数组以包含其数据。后备数组可能与数据大小完全相同,也可能大很多倍。在此示例中,a 大得多,因为其后备数组的大小为 5000,而其他后备数组的大小均为 1:

fun example1() {
    val values = arrayOf(1, 2, 3)
    
    val a = ArrayList<Int>(5000).apply {
        addAll(values)
    }
    
    val b = arrayListOf(values[0])
    val c = arrayListOf(values[1])
    val d = arrayListOf(values[2])
}

但是如果你让后备数组和数据的大小完全一样,那么bcd的内存加起来会多几个字节比 a 因为 class 每个实例使用的其他内存。 ArrayList 包含一个 int 大小参数,并且对于任何 class.

的实例也有一些基本内存开销
fun example2() {
    val values = arrayOf(1, 2, 3)

    val a = arrayListOf(*values)

    val b = arrayListOf(values[0])
    val c = arrayListOf(values[1])
    val d = arrayListOf(values[2])
}

如果我们使用 LinkedList,则没有支持数组,因此内存使用与数据量成线性比例。与示例 2 相同,将有更多字节用于附加实例。

fun example3() {
    val values = arrayOf(1, 2, 3)

    val a = values.toCollection(LinkedList())

    val b = LinkedList<Int>().apply { add(values[0]) }
    val c = LinkedList<Int>().apply { add(values[1]) }
    val d = LinkedList<Int>().apply { add(values[2]) }
}

还有子列表,它们只是来自另一个列表的数据的视图。这里的比较是模糊的,因为 bcd 共享与 a 使用的相同的后备数组。

fun example4() {
    val a = (0..999).toCollection(ArrayList(1000))

    val b = a.subList(0, 334)
    val c = a.subList(334,667)
    val d = a.subList(667,1000)
}