1. 栈和堆的概念
1.1 js的数据类型
值类型:数字number , 布尔 Boolean, 字符串string, 空null , 未定义的undefined
引用数据类型: 数组array , 对象 object , 函数function
区别:基本数据类型就是简单的数据段,引用数据类型是指由多个值构成的对象。
基本数据类型是按值访问,因为可以直接操作保存在变量中的实际值。存储在栈中。
引用类型是保存在堆内存中的对象,无法直接访问,只能通过操作对象在栈中的内存地址去调用。
1.2 栈
栈(stack):栈内存的简称,栈会自动分配内存空间,会自动释放,存放基本类型,简单的数据段,占据固定大小的空间。线性结构,后进先出,便于管理。
1.3 堆
堆(heap):动态分配的内存,大小不定也不会自动释放,存放引用类型,指那些可能由多个值构成的对象,保存在堆内存中,包含引用类型的变量,实际上保存的不是变量本身,而是指向该对象的指针。一个混沌,杂乱无章,方便存储和开辟内存空间。
引用类型是通过拷贝和new出来的,这样的数据存储于堆中。其实,说存储于堆中,也不太准确,因为,引用类型的数据的地址指针是存储于栈中的,当我们想要访问引用类型的值的时候,需要先从栈中获得对象的地址指针,然后,在通过地址指针找到堆中的所需要的数据。
1.4 堆和栈的区别:
栈:所有在方法中定义的变量都是放在栈内存中,随着方法的执行结束,这个方法的内存栈也自然销毁。
优点:存取速度比堆快,仅次于直接位于CPU中的寄存器,数据可以共享;
缺点:存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。
堆:堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(参数传递)。创建对象是2为了反复利用,这个对象将被保存到运行时数据区。
2. js内存模型
在栈内存中,我们可以细分为 地址和值,每当我声明一个变量就会为它创建一个地址以及值(包括null 等);我们调用的时候按址调用。堆内存在栈内存中也会创建一个栈的地址,然后他的值是在堆中的地址。
传值和传址:
var arr1 = [1,2,5,8];
var arr2 = arr1 ;
var str1 = arr1[2];
console.log(arr2); //1,2,5,8
console.log(str1); //5
arr2[4] = 99;
str1 = 6;
console.log(arr1); //1,2,5,8,99
console.log(arr1[2]); //5
因为arr1是数组,属于引用类型,所以它赋予给arr2的时候传的是栈中的地址(相当于新建了一个不同名“指针”),而不是堆内存中的对象的值。str1得到的是一个基本类型的赋值,因此,str1仅仅是从arr1堆内存中获取了一个数值,并直接保存在栈中。arr1、arr2都指向同一块堆内存,arr2修改的堆内存的时候,也就会影响到arr1,str1是在栈中新创建了一个地址和值,并将str1指向新创建的地址,直接将当前的值赋给他,并不能影响到arr1堆内存中的数据。
JS环境中分配的内存一般有如下生命周期:
内存分配:当我们申明变量、函数、对象的时候,系统会自动为他 们分配内存
内存使用:即读写内存,也就是使用变量、函数等
内存回收:使用完毕,由垃圾回收机制自动回收不再使用的内存
JavaScript有自动垃圾收集机制,他的原理就是找出那些不再继续使用的值,然后释放其占用的内存。垃圾收集器会每隔固定的时间段就执行一次释放操作。
在JavaScript中,最常用的是通过标记清除的算法来找到哪些对象是不再继续使用的,因此 a = null 其实仅仅只是做了一个释放引用的操作,让 a 原本对应的值失去引用,脱离执行环境,这个值会在下一次垃圾收集器执行操作时被找到并释放。而在适当的时候解除引用,是为页面获得更好性能的一个重要方式。
在局部作用域中,当函数执行完毕,局部变量也就没有存在的必要了,因此垃圾收集器很容易做出判断并回收。但是全局变量什么时候需要自动释放内存空间则很难判断,因此在我们的开发中,需要尽量避免使用全局变量,以确保性能问题。
以Google的V8引擎为例,在V8引擎中所有的JAVASCRIPT对象都是通过堆来进行内存分配的。当我们在代码中声明变量并赋值时,V8引擎就会在堆内存中分配一部分给这个变量。如果已申请的内存不足以存储这个变量时,V8引擎就会继续申请内存,直到堆的大小达到了V8引擎的内存上限为止(默认情况下,V8引擎的堆内存的大小上限在64位系统中为1464MB,在32位系统中则为732MB)。
另外,V8引擎对堆内存中的JAVASCRIPT对象进行分代管理。新生代:新生代即存活周期较短的JAVASCRIPT对象,如临时变量、字符串等;
老生代:老生代则为经过多次垃圾回收仍然存活,存活周期较长的对象,如主控制器、服务器对象等。