您现在的位置是:首页 > 干货小店干货小店
js递归函数造成的内存溢出(堆栈溢出)问题的解决方法
YU到边2022-03-10【干货小店】人已围观
简介关于堆栈的溢出问题,在 Javascript 日常开发中很常见,网上关于这类问题还是比较多的。本文旨在描述如何解决此类问题。
function
isEven (num) {
if
(num === 0) {
return
true
;
}
//业余草:www.xttblog.com
if
(num === 1) {
return
false
;
}
//业余草:www.xttblog.com
return
isEven(Math.abs(num) - 2);
}
//Outputs: true
console.log(isEven(10));
//Outputs: false
console.log(isEven(9));
上面的程序,看起来没有任何问题,运行几次也看不出来有什么问题。然而当我们让上面的参数改为 10000 的时候,会发现有内存泄漏、堆栈溢出问题。
//不同的javascript引擎报错可能不同
//Outputs: Uncaught RangeError: Maximum call stack size exceeded
console.log(isEven(10000));
原因是每次执行代码时,都会分配一定尺寸的栈空间(Windows系统中为1M),每次方法调用时都会在栈里储存一定信息(如参数、局部变量、返回值等等),这些信息再少也会占用一定空间,成千上万个此类空间累积起来,自然就超过线程的栈空间了。那么如何解决此类问题?
function
isEven (num) {
if
(num === 0) {
return
true
;
}
if
(num === 1) {
return
false
;
}
//业余草:www.xttblog.com
return
function
() {
return
isEven(Math.abs(num) - 2);
}
}
//Outputs: true
console.log(isEven(4)()());
此时每次调用时,返回一个匿名函数,匿名函数执行相关的参数和局部变量将会释放,不会额外增加堆栈大小。
优化调用
function
isEven (num) {
if
(num === 0) {
return
true
;
}
if
(num === 1) {
return
false
;
}
return
function
() {
return
isEven(Math.abs(num) - 2);
}
}
function
trampoline (func, arg) {
var
value = func(arg);
while
(
typeof
value ===
"function"
) {
value = value();
}
return
value;
}
//Outputs: true
console.log(trampoline(isEven, 10000));
//业余草:www.xttblog.com
//Outputs: false
console.log(trampoline(isEven, 10001));
通过上面的两种办法,都可以解决这类js递归函数造成的内存泄漏、堆栈溢出问题。
Tags:
很赞哦! ()
下一篇:到底什么是CDN?
相关文章
随机图文
-
到底什么是CDN?
CDN的全称是Content Delivery Network,即内容分发网络 -
鬼吹灯最精彩是哪一部
下面是作者对自己作品章节的依次评价与创作历程 -
深入浅出聊聊前端本地储存
我个人是非常看好 IndexedDB 的,我认为在前端越来越复杂的未来,在下一个十年各种重前端应用(在线文档,各种 SaaS 应用),以及 Electron 环境中,IndexedDB 一定能够大放光彩 -
从2K到40K之的非科班前端老司机
朋友们大家好,我是大圣啊。今天大家期待已久的这个职业生涯终于录完了,主要分享一下讲我11年毕业以后呢,从比较迷茫的状态,然后到12年自学编程,成为一个月薪2K的一个程序员,就到16年的能够达到月薪40K,一个很职业的一个程序员的一个心路历程吧