学习八、JavaScript的内存管理及垃圾回收(GC算法)

一、内存管理

    1) 内存:由可读写单元组成,表示一片可操作空间

    2) 管理:人为的去操作一片空间的申请,使用和释放

    3) 内存管理:开发者主动申请空间,使用空间,释放空间

    4) 管理流程:申请————使用————释放

二、垃圾回收与常见 GC 算法

1、JavaScript中的垃圾回收

      1) JavaScript 中的内存管理是自动的

      2) 对象不再被引用时是垃圾

      3) 对象不能从根上访问到时是垃圾

JavaScript的可达对象:我们可以访问到的对象就是可达对象(引用、作用域链)

      ————可达的标准就是从根上触发是否能够被找到

JavaScript中的根可以理解为是全局变量对象

2、GC的定义与作用

        1) GC就是垃圾回收机制的简写

        2) GC可以找到内存中的垃圾、并释放和回收空间

            程序中不再需要使用的对象、程序中不能再访问到的对象

        3) 算法就是工作时查找和回收所遵循的规则

        (引用计数、标记清除、标记整理、分代回收)

3、 引用计数算法:

        核心思想:设置引用数,判断当前引用数是否为0

        引用计数器

        引用关系改变时修改引用数字

        引用数字为0时立即回收

        优点  发现垃圾时立即回收,最大限度减少程序暂停

        缺点  无法回收循环引用的对象,资源消耗比较大

4、 标记清除算法:

        核心思想:分标记和清除两个阶段完成

        遍历所有对象找到并标记活动对象

        遍历所有对象清除没有标记的对象

        回收相应的空间

        优点  可以找到一些局部作用域的垃圾,可以解决引用计数算法中无法回收循环引用的问题

        缺点  不会立即回收垃圾对象,地址不连续、空间碎片化、浪费空间

5、 标记整理算法:

        标记整理可以看作是标记清除的增强

        标记阶段的操作和标记清除一致

        清除阶段会先执行整理,移动对象位置

        优点  减少碎片化空间

        缺点  不会立即回收垃

三、V8 引擎的垃圾回收

    1) V8是一款主流的JavaScript执行引擎

    2) V8采用即时编译

    3) V8内存设限(64位1.5G,32位800MB)

    1、V8垃圾回收策略

        1) 采用分代回收的思想

        2) 内存分为新生代、老生代

    2、V8中常见的GC算法

        * 分代回收

        * 空间复制

        * 标记清除

        * 标记整理

        * 标记增量

    3、V8如何回收新生代对象

        1) V8内存空间一分为二

        2) 小空间用于存储新生代对象(32M | 16M)

        3) 新生代制的是存活时间较短的对象

        新生代对象回收实现:

        1) 回收过程采用复制算法+标记整理

        2) 新生代内存区分为二个等大空间,使用空间为From,空闲空间为To

        3) 活动对象存储于From空间

        4) 标记整理后将活动对象拷贝至To

        5) 清除From空间完成释放,并交换From和To的空间

    回收细节说明

        1) 拷贝过程中可能出现晋升

        2) 晋升就是将新生代对象移动至老生代

        3) 一轮GC还存活的新生代需要晋升

        4) To空间的使用率超过25%时会将所有To空间中的对象晋升

    4、V8如何回收老生代对象

        1) 老生代对象存放在老生代区域

        2) 大空间用于存储老生代对象(1.4G | 700M)

        3) 老生代对象就是指存活时间较长的对象(全局变量,闭包)

        老生代对象回收实现:

        1) 主要采用标记清除、标记整理、增量标记算法

        2) 首先使用标记清除完成垃圾空间的回收

        3) 采用标记整理进行空间优化(当新生代晋升老生代时,老生代空间的碎片不足以存放时)

        4) 采用增量标记进行效率优化

    5、增量标记优化垃圾回收

        程序执行时交替执行垃圾回收处理,分层遍历对象进行标记,最后完成清除。

四、Performance 工具

    1、GC的目的是为了实现内存空间的良心循环

    2、良心循环的基石是合理使用

    3、时刻关注才能确定是否合理

    4、Performance提供多种监控方式

    5、使用步骤:

        1) 打开浏览器输入目标网址

        2) 进入开发人员工具,选择性能

        3) 开启录制功能,访问具体界面

        4) 执行用户行为,一段时间后停止录制

        5) 分析界面中记录的内存信息

五、如何判断内存的问题

    1、内存问题的体现

        1) 页面出现延迟加载或者经常性暂停:频繁的垃圾回收,程序代码产生的垃圾过多

        2) 页面持续性出现糟糕性能表现:内存膨胀,当前界面为了达到一定的使用速度,会去申请一定的使用空间,这个空间的大小远超过我们能够提供的空间大小

        3) 页面的性能随时间延长越来越差:内存泄漏,由于某种原因无法被回收的内存。

    2、界定内存问题的标准

        1) 内存泄漏:内存持续升高

        2) 内存膨胀:在多数设备上都存在性能问题

        3) 频繁垃圾回收:通过内存变化图进行分析

    3、监控内存的几种方式

        1) 浏览器任务管理器

            打开浏览器,通过shift+esc打开任务管理器,右击打开JavaScript使用内存

            如果小括号里的内存一直增加没有进行消耗,就存在内存泄漏问题

        2) Timeline时序图记录

            打开浏览器,F12,找到Performance,录制屏幕,监控内存走势

        3) 堆快照查找分离DOM

            什么是分离DOM:从当前的DOM树上脱离了,在JS代码中被引用。

            打开浏览器,F12,找到Memory,选择Profiles=>Heap snapshot=>takeSnapshot=>筛选'deta'就可以得到所有分离DOM

        4) 判断是否存在频繁的垃圾回收

            当GC工作状态,应用会假死,如果GC频繁且过长,用户会感受到比较差的性能体验

            Timeline中频繁的上升下降

猜你喜欢

转载自blog.csdn.net/qq_40289624/article/details/108897534