先奉上大佬文章地址表示感谢: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的来回切换了,直接来我这里吧,你在那里只会瞎占空间,影响小老弟后续的内存分配.”