zoukankan      html  css  js  c++  java
  • JS—垃圾回收

    JS是使用垃圾回收的语言,即:执行环境负责在代码执行时管理内存。

    基本思路:

    • 确定哪个变量不会再使用,然后释放它占用的内存。
    • 这个过程是周期性的,即垃圾回收程序每隔一定时间(或者说代码执行过程中某个特定的时间)就会自动运行。
    • 浏览器的发展史上,用到过两种主要的标记策略:标记清理引用计数

    1.标记清理

    JS最常用的垃圾回收策略

    • 当变量进入上下文,如在函数内部声明一个变量时,这个变量会被加上存在于上下文中的标记
    • 当变量离开上下文时,会被加上一个离开上下文的标记
    • 垃圾回收程序运行的时候,会标记内存中存储的所有变量。然后,它会将所有在上下文中的变量,以及被在上下文中的变量引用的变量的标记去掉。在此之后再被加上标记的变量就是待删除的了,原因是任何在上下文中的变量都访问不到它们了。随后垃圾回收程序做一次内存清理,销毁带标记的所有值并收回它们的内存。

    2.引用计数

    没有那么常用。

    思路是对每个值都记录它被引用的次数,以此判断是否需要清除

    有一个严重的问题就是循环引用。即A引用B,B引用A。但是A和B是孤立存在的。没有被其他的引用。如果函数被多次调用,则会导致大量内存永远不会被释放

    3.内存管理

      在使用垃圾回收的编程环境中,开发者通常午需关心内存管理。不过JS运行在一个内存管理与垃圾回收都很特殊的环境。分配给浏览器的内存通常比分配给桌面软件的要少很多,分配给移动浏览器的就更少了。这更多出于安全考虑而不是别的,就是为了避免运行大量 JavaScript 的网页耗尽系统内存而导致操作系统崩溃。这个内存限制不仅影响变量分配,也影响调用栈以及能够同时在一个线程中执行的语句数量。

      将内存占用量保持在一个较小的值可以让页面性能更好。优化内存占用的最佳手段就是保证在执行代码时只保存必要的数据。如果数据不再必要,要么把它设置为null,从而释放其引用——解除引用:

    • 解除引用最 适合全局变量和全局对象的属性。
    • 局部变量在超出作用域后会被自动解除引用
    • 注意:解除对一个值的引用并不会自动导致相关内存被回收。解除引用的关键在于确保相关的值已经不在上下文里了,因此它在下次垃圾回收时会被回收

    (1)const和let声明变量来提升性能

    ES6新增这两个关键字不仅有助于改善代码风格,而且同样有助于改进垃圾回收的过程。因为const和let都是块级作用域。使用这两个新关键字能更早地让垃圾回收程序介入,尽早回收应该回收地内存。在块级作用域比函数作用域更早终止地情况下,这就有可能发生。

    (2)隐藏类和删除操作

      根据JS所在地运行环境,有时候需要根据浏览器使用地JS引擎来采取不的性能优化策略。

      Chrome使用V8引擎,V8将解释后的JS代码编译为实际的机器码时会利用“隐藏类”,这对代码性能非常重要:

      原理暂时没有看懂,见JavaScript高级程序设计内存管理-隐藏类

    总而言之,两条要求:

    • 避免JS的先创建再补充式的动态属性赋值,并在构造函数中一次性声明所有属性
    • 把不想要的属性设置为null。可以保持隐藏类不变和继续共享

    (3)内存泄漏

    写得不好的JS可能出现难以察觉且有害的内存泄露问题。在内存有限的设备上,或者在函数会被调用很多次的情况下,内存泄漏可能是个大问题,JavaScript 中的内存泄漏大部分是由不合理的引用导致的。

    常见造成内存泄漏的原因:

    • 意外声明全局变量:如没有使用关键字声明变量,解释器会把变量当作window的属性来创建
    • 定时器的回调
    • 闭包导致

    (4)静态分配与对象池

    说明:静态分配是优化的一种极端形式。如果你的应用程序被垃圾回收严重地拖了后腿,可以利用它提升性能。但这种情况并不多见。大多数情况,这都属于过早优化,因此不用考虑。

  • 相关阅读:
    electron—Chromium有酒,Node有肉
    .NET 应用程序运行提示"!!0[] System.Array.Empty()找不到方法"的解决办法
    安装.Net Framework 4.6.2时出现“无法建立到信任根颁发机构的证书链”解决方法
    Electron入门
    npm使用淘宝镜像安装包
    MySQL Unable to convert MySQL date/time value to System.DateTime的解决办法
    axios无法在ie9,10,11环境下运行的问题解决
    解决ini-parser解析ini文件中文乱码问题
    git的tag,branch操作
    java类加载器
  • 原文地址:https://www.cnblogs.com/codexlx/p/14277721.html
Copyright © 2011-2022 走看看