Loops 方案-为什么内存终止?
有3个程序,我试图了解堆栈和堆中发生了什么。 都是无限循环 一, 所有应用程序都是尾部递归,堆栈正常。 只创建了2个lambda,因此堆是正常的。 我说得对吗 二, 所有应用程序都是尾部递归,堆栈正常。 关于堆:创建了无限个lambda(lambda()'ok')。 我说得对吗? -那么为什么内存没有终止呢 最后一点: 三, 2和3的区别是什么?为什么在2内存终止? 如果我在一个循环后的第3个循环中正确地欠下:Loops 方案-为什么内存终止?,loops,scheme,Loops,Scheme,有3个程序,我试图了解堆栈和堆中发生了什么。 都是无限循环 一, 所有应用程序都是尾部递归,堆栈正常。 只创建了2个lambda,因此堆是正常的。 我说得对吗 二, 所有应用程序都是尾部递归,堆栈正常。 关于堆:创建了无限个lambda(lambda()'ok')。 我说得对吗? -那么为什么内存没有终止呢 最后一点: 三, 2和3的区别是什么?为什么在2内存终止? 如果我在一个循环后的第3个循环中正确地欠下: we activate this: (lambda (a b) (a a (la
we activate this: (lambda (a b) (a a (lambda () (b)))
on (lambda (a b) (a a (lambda () (b)))
and this (lambda () 'ok) (becuse this is (b)..)
这和2是一样的 在智能编译器中,案例1和案例2是等效的。即使没有智能编译器,每次都会重新创建lambda,案例2可能会创建无限多的lambda,但它们可以立即进行垃圾收集。所以结果是一样的:恒定的堆栈和堆使用率 在案例3中,每个新lambda都包含一个对前一个lambda的免费引用,因此创建的lambda都不是垃圾回收的。您仍然有恒定的堆栈使用率,但堆使用率将膨胀。(一个真正聪明的编译器可以发现lambda实际上是未使用的,并完全消除它,但我关于自由引用的一般观点是正确的。) 如果编译器可以证明
b
已经是一个空(-only)过程,和/或如果它可以证明生成的lambda将仅以空方式调用(否则,它必须添加类型和算术检查器),那么它也可以直接用b
替换(lambda()(b))
。同样,要将这一点应用到您的示例中,需要一个非常智能的编译器。谢谢!你能解释为什么“每个新的lambda包含一个对先前lambda的自由引用”(lambda()(b))
包含一个对b
的自由引用,即先前的lambda。因此,只要这个新lambda持有对它的引用,就不能收集后者。
(let ((f (lambda (a b)
(a a (lambda () 'ok)))))
(f f (lambda () 'ok)))
(let ((f (lambda (a b)
(a a (lambda () (b))))))
(f f (lambda () 'ok)))
we activate this: (lambda (a b) (a a (lambda () (b)))
on (lambda (a b) (a a (lambda () (b)))
and this (lambda () 'ok) (becuse this is (b)..)