GC算法1、引用计数核心思想:设置引用次数,判断当前引用是否为0优点:发现垃圾后,立即回收,最大限度减少程序停顿缺点:无法回收循环引用的对象,耗时较长(需要监听计数值的变化)functionfn(){constobj1={}constobj2={}}2.标记清除核心思想:标记清除两个阶段缺点:1.空间碎片(地址不连续被回收的对象)2.不能马上被回收3.标记整理标记,然后整理活动对象的地址,尽量让活动对象的地址连续新生代的内存区域是分成两个大小相等的空间。已用空间为From,用于存放活动对象,空闲空间为To,用于存放From中的活动对象。活动对象存放在From空间,活动对象标记后复制到ToFrom。与To交换空间完成释放和恢复细节:From和To之间的复制过程可能会被提升(将新生代对象移动到老年代)。以下两种情况会导致晋升轮存活下来的年轻代需要晋升到To空间使用率超过25%。回收老年代对象空间大,无法使用复制算法。使用增量标记方式来优化效率。标记清除标记:使活动对象的地址连续标记增量:将原来的标记和排序工作拆分成多个小的标记工作,防止程序阻塞V8v8垃圾回收策略v8内存有上限采用分代回收思想内存分为新生代,老年代针对不同的对象采用不同的算法增量频繁的GC(垃圾回收)带来了什么?当GC工作时,应用程序停止。频繁且长时间的GC会导致应用程序卡死。用户感觉应用程序在使用过程中卡住了。如何判断是否频繁收集垃圾:Timeline中频繁上升任务管理器中数据频繁上升减少减少heapsnapshot搜索分离dom,这些都是无用的dom引用,需要使用heapsnapshot功能超查找detachedNodev8引擎执行过程代码优化函数嵌套会导致v8进行多次预解析,所以栈操作不要嵌套太深js执行环境执行环境栈(ECStack,执行上下文栈)执行上下文VO(G),全局变量对象EC(g)、全局执行上下文基本类型(栈操作)基本数据类型是Operatebyvalue基本数据类型的值存放在栈区。无论我们当前看到的栈内存还是后续引用数据类型将要使用的堆内存,都属于计算机内存GO(都是局部对象)引用类型(堆操作)函数执行判断作用域链(当前执行上下文,上级执行上下文)判断这一点,如果是在全局作用域,那么就是窗口初始化arguments对象参数赋值变量提升(var声明字的key,或者函数内部的函数语句)执行代码,如果函数没有被其他地方引用,那么会进行入栈操作,释放栈内存闭包理解函数fn(){vara=1returnfunction(b){console.log(a+b)}}constf=fn()f(5)f10()闭包是一种通过私有上下文保护其中变量的机制。也可以认为,创建的某个执行上下文没有释放时,形成一个闭包保护,保存数据,循环添加事件。查看闭包的权衡。如果使用闭包,请注册多个事件。由于关闭,您将申请的地址保存下来。如果有更多的事件,将请求更多的内存。因此,变量声明最好放在局部变量中,否则代码执行时会更难在作用域链上找到变量。花时间使用jsbench工具比较下面两段代码vari,str=""functionparseDom(){for(i=0;i<100;i++){str+=i}}parseDom()functionparseDom(){letstr=''for(leti=0;i<100;i++){str+=i}}parseDom()多次使用变量缓存数组长度dom变量等减少判断层次减少判断为尽可能多的层级,如果有嵌套判断,看能不能把判断条件往外解除,减少循环体活跃度
