node深度循环,循环里面有插入数据的操作。回调一直不执行。然后报内存溢出
发布于 9 年前 作者 wustxing 4732 次浏览 最后一次编辑是 8 年前 来自 问答

var s=new Array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24); var sql="INSERT INTO DoubleBall (redball,basketball) VALUES "; var e=0; var f=5000; for(var c=0; c< s.length-5;c++) { for (var b = c+1; b < s.length - 4; b++) { for (var a = b + 1; a < s.length - 3; a++) { for (var i = a + 1; i < s.length - 2; i++) { for (var j = i + 1; j < s.length - 1; j++) { for (var k = j + 1; k < s.length; k++) { for(var d=1;d<=10;d++) { e++; if(e<=f) { var txt = “[” + s[c] + “,” + s[b] + “,” + s[a] + “,” + s[i] + “,” + s[j] + “,” + s[k] + “]”; var doubleball = new DoubleBall({ redball: txt, basketball: d }); sql += “(’” + doubleball.redball + “’,” + doubleball.basketball + “),”; if(e==f) { console.log(sql); doubleball.save(sql,function (err, doubleball) { if (err) { console.log(err); } else { console.log(“5000成功\n”); } }); f+=5000; } } } } } } } } } 报错FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory

15 回复

这个用async.times 来代替吧,这个会造成内存溢出的

@kenshinhu 是的。就是报内存溢出错误。用aysnc.times怎么代替。。能详细点么

工作中遇到这种情况,我会考虑优化sql,做批量处理。

代码看得好纠结- -

两点: 第一点:全选然后Tab 第二点:虽然node强在io上(因为他不用等到io结束后再执行下一个),但是跟程序猿的水平有直接关系。举个列子:io不阻塞相当于你塞给一个工人一项工作,工人说你走吧,我会做完了。但是此时他可能还没开始做,接下来你又丢给他一项工作 ,工人说你走吧,我会作完的。for的过程是不停的同步创建工作,工人不可能作完同时来的那么多工作,加上你的深度嵌套,最后超过一个进程最大内存限制,崩掉很正常。

@haozxuan 对。这个原理我清楚。只是在想如果遇到这种情况用node我该怎么处理,可不可以用其他的方式绕过这个。。纠结。有解决这类问题的方案么,现在。谢谢了。

@leapon 我现在这已经是批量处理了。。。5000条一次的插入。

@DevinXian 不好意思哈。。不知道怎么贴上有格式的代码

@wustxing node强在io上,对于数据的循环这样的cpu密集型运算,他并不强,你可以写个c++ 插件,或者换成php做这样的事情。如果很执着用node的话就调整V8内存限制。。。

@haozxuan 嘿嘿。。谢谢啦。。我还在想要不要用多线程来实现那个循环。比如五千条一个线程。但是具体我不知道怎么弄。不知道你觉得多线程可以解决这个问题么?

@wustxing Markdown, 入门只需要最多30min

懒一点的话,直接cluster方式多进程处理,效果显著,但要注意内存使用率

@joney-pinkman 谢谢。你的意思是说多进程处理是可行的么?

是的,对数据分批次处理,同时对进程监控,对处理完的进程继续cluser出来,充分榨干性能,效果才能显著提升,不过如果单纯用原生api的话,比较复杂,最好看下有什么cluster库能用吧

回到顶部