【问题标题】:Erlang - Looping and Memory AllocationErlang - 循环和内存分配
【发布时间】:2017-05-03 20:06:27
【问题描述】:
在 Erlang 中为进程创建循环的典型方法是使用递归:
keepAlive(someArg) ->
% do something,
keepAlive(someValue)
由于 Erlang 中的变量是不可变的,当我在这样的循环中声明一个局部变量时会发生什么?它会在下一次递归调用中收集垃圾吗?即使没有声明新变量,这样的循环也不是问题,并且可能导致堆栈溢出,因为从一个循环到另一个循环,您会得到无穷无尽的指针,理论上可能不得不一直回到某个点?
【问题讨论】:
标签:
memory-management
garbage-collection
erlang
【解决方案1】:
从技术上讲,局部变量没有在 Erlang 中声明。他们注定要珍惜。局部变量的值存储在堆栈中。某些数据类型可以直接存储在堆栈中,而不必在堆上分配。因此,局部变量不必被垃圾收集,但某些数据类型的值必须被垃圾收集。无论如何,这些值不会在下一次递归调用中被垃圾收集,而是当堆遇到堆栈时,这意味着堆已满并触发垃圾收集。
最重要的是,如果您以您描述的方式编写函数,则在递归调用和参数存储在“寄存器”之前释放堆栈帧。然后下一个递归调用不是函数调用而是跳转。这意味着堆栈不会增长。所有在堆上分配且不再被堆栈或函数参数引用的值都可以被垃圾收集,因此不会出现内存泄漏或堆栈溢出。事实上,这是一个非常简单优雅的解决方案。