Node 内存溢出及V8垃圾回收机制

先奉上大佬文章地址表示感谢:https://www.jianshu.com/p/74a466789ff4

问题复现,题目和代码如下

//给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
//
// 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
//
//
// 示例:
//
// 给定 nums = [2, 7, 11, 15], target = 9
//因为 nums[0] + nums[1] = 2 + 7 = 9
//所以返回 [0, 1]

var twoSum = function(nums, target) {
  var result = [];
  var num1;
  var num2
  nums.map((item,index)=>{
    for(let i = index+1;i<nums.length;i++){
      var sum = item+nums[i];
      result.push(sum);
      if(sum === target) {
        num1= index;
        num2 = i;
      }
    }
  });
  return [num1,num2]
};
console.log(twoSum([1,2,6,7,8],15))   // [3,4]

当传入一个长度为12599的数组时,报错内存溢出:
在这里插入图片描述
出现原因:
js的对象是存储在堆内存中的,在node中使用内存默认存在限制,64位系统下大概是1.4GB,32位系统大概是0.7GB.这里在提交代码是测试的数组长度是12599,根据我的代码 result长度是79361101.大概在75…的时候报错,内存溢出.

解决办法
1.修改代码,直接不要result就好了,本来result也没什么用~~

var twoSum = function(nums, target) {
  var num1;
  var num2
  nums.map((item,index)=>{
    for(let i = index+1;i<nums.length;i++){
      var sum = item+nums[i];
      if(sum === target) {
        num1= index;
        num2 = i;
      }
    }
  });
  return [num1,num2]
};

2.既然是内存溢出,那么能不能修改内存大小呢?

果然度娘啥都知道,修改命令如下:

node --max-new-space-size=1024 app.js // 单位为KB   设置新生代内存最大值
node --max-old-space-size=2000 app.js // 单位为MB   设置老生代内存最大值

关于新生代和老生代这就涉及到V8的垃圾回收机制了!!

V8的垃圾回收机制

分代式垃圾回收机制,也就是v8按照对象的存活周期把内存分为新生代和老生代两种内存空间,然后针对不同的内存使用更高效的算法.

新生代(New Space):保存存活时间较短的对象,在新生代中主要通过Scavenge算法将内存空间分为from和to两个空间,分配对象时先从from中分配,当开始进行垃圾回收的时候,将from中的存活对象复制到to内存块,然后释放非存活对象的内存空间.完成复制之后,两个空间角色互换,以此循环使用.

老生代(Old Space):保存存活时间长或者常驻的对象.在老生代中采用Mark-sweep算法(标记清除)跟Mark-Compat算法(标记整理)结合的方式来进行垃圾回收.

Mark-sweep**先遍历所有对象并标记存活的对象,在随后的清除阶段只清除标记之外的对象.

缺点:进行一次垃圾回收之后,内存变得碎片化,无法完成分配一个较大的对象内存.

这时候结合Mark-Compat算法就很完美了:该算法在标记存活对象之后,在整理的过程中,把活的对象全部挪到一端去,移动完成后直接清理掉边界外的内存,这样就避免了内存碎片化的问题.

新生代中的存活周期长的对象能不能到老生代里面去呢??

老生代说:“想来可以,我先看看你有没有被Scavenge这个家伙回收过,以此来判断你在哪(from空间还是to空间).其次我还得看看你的to空间内存占比超没超过25%,如果超过了你就不用from to的来回切换了,直接来我这里吧,你在那里只会瞎占空间,影响小老弟后续的内存分配.”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值