在JavaScript中,当我们创建变量时,系统会自动给对象分配对应的内存。
基本类型的值在内存中会占据固定的内存空间,它们的值都保存在栈空间中,直接可以通过值来访问这些。
而引用类型的值大小不固定,在栈内存中存放地址指向堆内存中的对象,是通过引用来访问的。
栈内存中的基本类型,可以通过操作系统直接处理,而堆内存中的引用类型,正是由于可以经常变化,大小不固定因此需要JavaScript引擎通过垃圾回收机制来处理。
在chrom中JavaScript的v8引擎被限制了内存的使用,根据不同的操作系统内存大小会不同。
原因:
在64为操作系统下,新生代回收的空间为32MB,因为新生代中的变量存活时间短,不太容易产生太大的内存压力,因此不够大也是可以理解的。
在新生代的回收空间中分为两部分,一部分是正在使用的内存空间,一部分是闲置的内存空间。
当开始进行垃圾回收时,JavaScript引擎会将正在使用的内存空间检查一遍,如果检测是存活对象,就会复制一份到闲置的内存空间中。
如果不是存活对象直接进行系统回收。
当左边内存中的对象没有了的时候,当再有新生代数据产生时,之前的闲置的内存空间和使用的内存空间对调。
新生代内存中的变量如果经过回收后依然一直存在,那么就会被放入到老生代内存中。
只要是经过一次Scavenge算法回收的就可以晋升为老生代内存的对象。但是当内存空间较大时,就不适合Scavenge算法。
老生代内存垃圾回收机制采用标记清除和标记整理的策略进行老生代内存中的垃圾回收。
标记清除分为两个阶段:标记阶段和清除阶段。
首先会遍历堆上的所有的对象,分别对他们打上标记,然后再代码执行过程结束之后,对使用过的变量取消标记。
在清除阶段,就会把还有标记的进行整体清除,从而释放内存空间。
在标记清除之后还是会出现内存碎片的问题,内存碎片多了之后,如果要新来一个较大的内存对象需要存储,会造成影响。
对于通过标记清除产生的内存碎片,需要通过标记整理策略进行解决。
经过标记清除阶段后,老生代内存中出现内存碎片。为了方便清除内存碎片,标记整理方法被提出,这个方法是在标记清除的基础上演进而来。
内存泄漏是指JavaScript中已经分配堆内存地址的对象由于长时间未释放或无法释放造成了长期占用内存,使内存浪费,最终导致运行的应用响应速度变慢以及最终崩溃的情况。
造成内存泄漏的原因:
优化: