哦,这里发生了很多事情!!!
让我们从Java开始
int[]。Java中的数组是唯一未类型擦除的集合。an
int[]的运行时表示形式与的运行时表示形式不同
Object[],因为它实际上
int直接使用。因此,使用它不会涉及拳击。
用内存的术语来说,内存中有40.000.000个连续字节,每当读取或写入一个元素时,就一次读取和写入4个字节。
相反,一个
ArrayList<Integer>以及几乎所有其他通用集合都由40.000.000或80.000.00个连续字节(分别在32位和64位JVM上)组成,加上80.000.000个字节在组中遍布内存8个字节。每次对元素的写操作都必须经过两个内存空间,而当您实际执行的任务如此之快时,处理所有这些内存所花费的时间非常重要。
因此,回到Scala,查看第二个示例,其中操作了
List。现在,Scala的
List名称更像Java的名称,而
linkedList不是严重的错误命名
ArrayList。a的每个元素
List由一个名为的对象组成,该对象
Cons具有16个字节,并带有指向该元素的指针和指向另一个列表的指针。因此,一个
List10.000.000元素由160.000.000个元素(以16字节为一组在内存中分布)加上80.000.000字节(所有8个字节以组为单位)组成。因此,真正的意义
ArrayList更在于
List
最后,
Range。A
Range是具有下边界和上边界以及步骤的整数序列。
Range10.000.000个元素的A
为40个字节:下限和上限和步长的三个整数(非通用),以及一些预先计算的值(
last,
numRangeElements)和用于
lazyval线程安全的其他两个整数。为了清楚起见,这 不是 10.000.000 的40倍:总共40个字节。范围的大小完全无关紧要,因为
它不存储各个元素 。只是下限,上限和步骤。
现在,由于a
Range是a
Seq[Int],它在大多数情况下仍然必须经过装箱:
int将a转换为an
Integer然后再转换为a
int,这是可悲的浪费。
缺点尺寸计算
因此,这是对Cons的初步计算。首先,请阅读本文,了解有关对象占用多少内存的一些一般准则。要点是:
- Java将8个字节用于普通对象,将12个字节用于对象数组,以用于“整理”信息(此对象的类是什么,等等)。
- 对象以8个字节的块分配。如果您的对象小于该对象,则将对其进行填充以对其进行补充。
我实际上以为是16个字节,而不是8个字节。无论如何,缺点也比我想象的要小。它的字段是:
public static final long serialVersionUID; // static, doesn't countprivate java.lang.Object scala$collection$immutable$$colon$colon$$hd;private scala.collection.immutable.List tl;
引用 至少为 4个字节(在64位JVM上可能更多)。因此,我们有:
8 bytes Java header4 bytes hd4 bytes tl
这使得它只有16个字节长。很好,实际上。在示例中,
hd将指向一个
Integer对象,该对象假定为8个字节长。至于
tl,它指向另一个缺点,我们已经在计算了。
我将修改估算值,并在可能的情况下提供实际数据。



