如何在Javascript中释放上一个堆栈帧的内存

How to free memory of previous stack frame in Javascript

本文关键字:堆栈 内存 上一个 释放 Javascript      更新时间:2023-09-26

我有很多函数调用链中的下一个函数,将一组相当大的数据处理为一组同样大的不同数据:

function first_step(input_data, second_step_callback)
{
  result = ... // do some processing
  second_step_callback(result, third_step);
}
function second_step(intermediate_data, third_step_callback)
{
  result = ... // do some processing
  third_step_callback(result);
}
function third_step(intermediate_data) { }
first_step(huge_data, second_step);

third_step中,我的内存不足(当内存使用量达到1.5GB左右时,Chrome似乎会扼杀选项卡)。

我认为,当到达third_step()时,来自first_step()input_data仍然被保留,因为first_step()在调用堆栈上,不是吗?至少在调试器运行时,我可以看到数据。

显然我不再需要它了。在first_step()中,在second_step_callback(result, third_step);之后没有代码。也许如果我能释放内存,我的选项卡可能会在处理这种大小的数据集时幸存下来。我能做这个吗?

如果没有看到更多关于使用内存的实际操作,我们很难判断您是只是使用了太多内存,还是只需要释放早期内存。

而且,Javascript中的内存不是由堆栈帧"拥有"的,所以这个问题的前提似乎有点错误。Javascript中的内存是垃圾收集的,当没有活动的、可访问的代码仍然引用数据时,它有资格进行GC,并且将在垃圾收集器下次运行时(在JS空闲时间)进行垃圾收集。

也就是说,如果你的代码像你的问题显示的那样进行了一系列嵌套函数调用,你可以通过做以下一些事情来减少内存使用量:

  1. 清除包含不再需要的大数据的变量(只需将它们设置为null
  2. 减少使用包含大量数据的中间变量
  3. 减少数据复制
  4. 减少具有中间结果的字符串操作,因为每个操作都会创建一块内存,然后必须回收这些内存
  5. 通过使用setTimeout()运行链中的下一步来清除堆栈,并让垃圾收集器有机会对早期的临时变量执行操作
  6. 重新构造处理或存储数据的方式,从根本上减少内存使用