node+mongoose.save out of memory
来源:互联网 发布:彩票双色球大赢家软件 编辑:程序博客网 时间:2024/06/07 03:16
在mongoose存入过程中node报出out of memory,由于之前数据量小的时候并没有这个错误,本次运行只是增加了数据量,因此将错误定位在存储的过程。
查了许久也没找到现成的方案让我ctrl+c,node新手+mongoose新手,只能靠自己猜、、幸好折腾了一天,才算有个解决方案。
一个小例子还原现场:
var mongoose = require('mongoose');mongoose.connect('mongodb://localhost/test', {useMongoClient: true});mongoose.Promise = global.Promise;mongoose.set("debug", true);var Cat = mongoose.model('Cat', { name: {type:String}, prop1: {type:String}, prop2: {type:String}, prop3: {type:String}, prop4: {type:String}, prop5: {type:String}, prop6: {type:String}, prop7: {type:String}, prop8: {type:String}, prop9: {type:String}});Cat.remove({}, function (err) { if (err) { console.log(err); } else { console.log("清空Cat"); }});for (var i = 0; i < 100000; i++) { var kitty = new Cat({ name: 'Zildjian', prop1: "prop1 of cat " + i, prop2: "prop2 of cat " + i, prop3: "prop3 of cat " + i, prop4: "prop4 of cat " + i, prop5: "prop5 of cat " + i, prop6: "prop5 of cat " + i, prop7: "prop5 of cat " + i, prop8: "prop5 of cat " + i, prop9: "prop5 of cat " + i }); kitty.save((function(index){ return function (err) { if (err) { console.log(err); } else { console.log('meow cat '+index); } }})(i));
为了让它迅速oom,设置了最大老生代空间为900,运行: node --max-old-space-size=900 ./bin/www
得到报错:
<--- Last few GCs ---> 72238 ms: Mark-sweep 817.6 (903.8) -> 817.5 (904.8) MB, 621.4 / 0.0 ms [allocation failure] [GC in old space requested]. 72867 ms: Mark-sweep 817.5 (904.8) -> 817.6 (906.8) MB, 629.2 / 0.0 ms [allocation failure] [GC in old space requested]. 73521 ms: Mark-sweep 817.6 (906.8) -> 823.0 (903.8) MB, 653.2 / 0.0 ms [lastresort gc]. 74167 ms: Mark-sweep 823.0 (903.8) -> 828.4 (903.8) MB, 646.2 / 0.0 ms [lastresort gc].<--- JS stacktrace --->==== JS stack trace =========================================Security context: 000002B9F4A3FA99 <JS Object> 2: write [D:\server\monitor\node_modules\mongodb-core\lib\connection\pool.js:984] [pc=0000022F20E09E62] (this=000001985C65C779 <a Pool with map 000000B3AF5B8DF9>,commands=000001F7DDC54471 <a Query with map 000000B3AF5B6F61>,options=000000645A4B4579 <an Object with map 000000B3AF584109>,cb=0000021F10211521 <JS Function resultHandler (SharedFunctionInfo 0000016FCCA4FAA9)>) 3: executeWri...FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
分析过程:
将原代码存入的数据量调为10只,看一下打印的结果:
鱼唇的我想了好久才想到可能是这样的(ps:以下过程全靠猜的,不一定对)
model.save(fn) 这个方法是异步的,它被调用结束才开始调用它的回调函数。
for循环中将save添加到待运行的队列,每执行一个save又将它的回调添加到队尾,因此,在所有save完成之前不会执行任何一个save的回调函数。
从输出的结果来看,也是将所有save运行完之后,再运行所有的回调函数。
而回调函数维护了自己的数据,这里,并不知道它维护了哪些,可能是比较大的。
在报出oom的时候,上一条输出依然还是mongoose的insert数据的记录,此时已经运行过的save函数,都添加了一个回调等待运行,可能是这些回调函数维护的数据占据了大量内存。
因此,想到一条存完之后,立刻执行它的回调函数,这样使回调函数维护的数据得以释放。
最终解决方案:一只一只存
var mongoose = require('mongoose');mongoose.connect('mongodb://localhost/test', {useMongoClient: true});mongoose.Promise = global.Promise;mongoose.set("debug", true);var Cat = mongoose.model('Cat', { name: {type:String}, prop1: {type:String}, prop2: {type:String}, prop3: {type:String}, prop4: {type:String}, prop5: {type:String}, prop6: {type:String}, prop7: {type:String}, prop8: {type:String}, prop9: {type:String}});Cat.remove({}, function (err) { if (err) { console.log(err); } else { console.log("清空Cat"); }});saveNextCat(0);function saveNextCat(i){ if(i<10000){ var kitty = new Cat({ name: 'Zildjian', prop1: "prop1 of cat " + i, prop2: "prop2 of cat " + i, prop3: "prop3 of cat " + i, prop4: "prop4 of cat " + i, prop5: "prop5 of cat " + i, prop6: "prop5 of cat " + i, prop7: "prop5 of cat " + i, prop8: "prop5 of cat " + i, prop9: "prop5 of cat " + i }); kitty.save((function(index){ return function (err) { if (err) { console.log(err); } else { console.log('meow cat '+index); } i++; saveNextCat(i); }})(i)); }else{ return; }}
更改过后的程序的输出为:
可以看到,存完之后立刻执行了回调函数,并在相同的最大老生代空间下使所有数据都存储完成。
阅读全文
0 0
- node+mongoose.save out of memory
- out of memory
- Out of memory
- out of memory
- android out of memory
- out of memory
- MATLAB: OUT OF MEMORY
- MATLAB out of memory
- 解决out of memory
- Out Of Memory
- android Out of memory
- linux out of memory
- matlab out of memory
- thrift out of memory
- Android Out Of Memory
- out of memory
- centos out of memory
- GP Out of memory
- 第七章预处理与结构体十个问题及解答
- mysql 触发器
- 【Android training】与其他应用交互 Intent
- 异常
- Nodejs 使用eventproxy来控制并发
- node+mongoose.save out of memory
- Java ArrayList的元素添加移除之java.util.ConcurrentModificationException异常分析
- 正则表达式
- 整理:npm安装太慢,切换镜像方法
- Android中LayoutParams总结
- 浅谈Tarjan算法——(1)
- 解决mysql和可视化工具Navicat与web应用中数据库传输中文乱码问题
- PHP计算时间,统计图表
- location.href.indexOf