我无法弄清楚Scala的不可变序列的某些操作的实现。我将以此为例:
def example: List[Int] = {
val list0 = List.range(1,10)
list0.tail
}
一旦函数完成执行,list0现在已超出范围。将list0的头部从内存中删除,或者list0保持不变,直到整个列表被垃圾收集?
答案 0 :(得分:6)
在您的示例中,list0
的头部将留给垃圾收集器进行收集,因为没有任何内容可以引用它。但是,在退出函数时,剩余的项目(尾部)将继续存在(假设呼叫的结果被分配给某些东西)。
列表中的每个单元格都会保留对列表中下一个单元格(或Nil
)的引用,但不是反之亦然。
答案 1 :(得分:1)
您正在创建总共12个(可能的)实体
list0
- 包含1到10的列表。list0.tail
。以下是最后一个大括号之前的概念性记忆图,这里是参考
Somewhere on JVM Stack list0(head)->1->2 ... ->10
|
Top of JVM Stack, contains returnList with head->|
当函数完成时,将弹出引用list0
,并且有资格进行垃圾回收。由于list0
是唯一引用1
的内容,1
也是垃圾收集的公平游戏。
元素2-10以及包含它们的返回列表将保留在堆上,因为正在运行的代码仍然可以访问引用example
的任何人。
希望这有帮助。