JavaScript 内存管理及垃圾回收
一、内存管理
JavaScript 是一种自动垃圾回收语言,这意味着 JavaScript 引擎会自动监测和清理无用的内存。
JavaScript 中的内存管理主要由 JavaScript 引擎负责,开发人员不需要手动管理内存。JavaScript 引擎使用垃圾回收算法来实现自动垃圾回收。
二、垃圾回收
JavaScript 垃圾回收算法是指在 JavaScript 程序中,用来回收不再使用的内存的算法。常见的垃圾回收算法包括:
- 标记-清除算法:标记出所有不再使用的对象,然后清除它们。
- 引用计数算法:维护每个对象的引用计数,当计数为0时回收对象。
- 标记-整理算法:标记出所有不再使用的对象,然后将所有存活的对象整理到一起,回收其他对象。
- 增量标记-整理算法:将垃圾回收过程分成多个小步骤执行,并且可以处理循环引用问题。
现代 JavaScript 引擎通常采用增量标记-整理算法或其他类似算法来实现垃圾回收。
1、标记-清除算法
标记-清除算法是通过标记未使用的内存块,然后清除这些标记的内存块来实现垃圾回收的。
标记-清除算法的工作流程如下:
- 从根节点开始,遍历所有可达的对象,将其标记为“可用”。
- 扫描内存中所有对象,将未被标记的对象标记为“不可用”。
- 清除所有不可用对象占用的内存。
标记-清除算法的优缺点
优点:
- 标记-清除算法简单易实现。
- 标记-清除算法可以回收任意类型的对象。
缺点:
- 标记-清除算法会产生碎片化的内存,这可能导致空间浪费。
- 标记-清除算法会产生暂停,这可能导致程序卡顿。
现在,由于标记-清除算法会产生碎片化的内存和暂停,所以现代的 JavaScript 引擎主要使用增量标记-整理算法来实现垃圾回收。增量标记-整理算法将垃圾回收过程分成多个小步骤执行,避免了长时间的暂停。
标记-清除算法是一种简单易实现的垃圾回收算法,但是会产生碎片化的内存和暂停,因此现在不再常用。
2、引用计数算法
引用计数算法是通过跟踪每个对象的引用次数来确定对象是否被使用,如果一个对象的引用次数为0,则该对象被视为垃圾并被回收。
引用计数算法的工作流程如下:
- 每当一个对象被引用时,将其引用计数增加1。
- 每当一个对象的引用被删除时,将其引用计数减少1。
- 当一个对象的引用计数为0时,该对象被视为垃圾并被回收。
引用计数算法的优缺点
优点:
- 引用计数算法可以实时回收垃圾。
- 引用计数算法可以较快地回收循环引用的对象。
缺点:
- 引用计数算法无法处理循环引用问题。如果两个对象相互引用,而没有其他变量引用它们,则它们的引用计数都为1,而它们都不能被回收。
- 引用计数算法会增加程序的运行时间和空间开销。
引用计数算法在处理循环引用问题上会有困难。而且引用计数算法会增加程序的运行时间和空间开销。因此现代的 JavaScript 引擎不再使用引用计数算法来实现垃圾回收。
引用计数算法的实现方式可以是各种各样的, 例如:
- 对于每一个对象都维护一个计数器,在有新的引用时将计数器加一,在引用结束时将计数器减一。
- 对于每一个对象维护一个引用链表,在有新的引用时将引用的对象加入链表中,在引用结束时将引用的对象移除链表。
虽然现在的 JavaScript 引擎不再使用引用计数算法来实现垃圾回收,但是对于引用计数算法的理解对于理解其他算法有很大帮助。
3、标记-整理算法
标记-整理算法是一种垃圾回收算法,它首先标记出所有不再使用的对象,然后将所有存活的对象整理到一起,回收其他对象。
标记-整理算法的工作流程如下:
- 标记:从根节点开始,遍历所有可达的对象,将其标记为“存活”。
- 整理:将所有存活的对象移动到一起,以便进行回收。
- 回收:回收所有未被标记的对象占用的内存。
标记-整理算法的优缺点
优点:
- 可以有效地处理循环引用问题。
- 可以减少内存碎片化。
缺点:
- 整理过程会影响性能。
- 需要额外的空间来存储活动对象和空闲对象。
标记-整理算法在处理循环引用问题上会有优势,减少内存碎片化,但是会影响性能,需要额外的空间来存储活动对象和空闲对象。
标记-整理算法是一种较为新的垃圾回收算法,相对于标记-清除算法和引用计数算法而言,它可以更好地解决循环引用问题。
在使用标记-整理算法进行垃圾回收时,系统会标记出所有仍然在使用的对象,然后将这些对象移动到一起,这样就可以避免内存碎片化,并且可以减少循环引用问题的影响。
但是,标记-整理算法也有缺点,整理过程会影响性能,需要额外的空间来存储活动对象和空闲对象。另外,在 JavaScript 引擎中,这种算法也没有得到广泛采用,大多数 JavaScript 引擎使用的是增量标记-整理算法或其他类似算法。
4、增量标记-整理算法
现代的 JavaScript 引擎主要使用增量标记-整理算法来实现垃圾回收,这种算法在运行时将垃圾回收过程分成多个小步骤来执行,避免了长时间的暂停。
增量标记-整理算法的工作流程如下:
- 标记:从根节点开始,遍历所有可达的对象,将其标记为“存活”。
- 整理:将所有未被标记的对象移动到一起,以便进行回收。
- 回收:回收所有未被标记的对象占用的内存。
增量标记-整理算法通过将垃圾回收过程分成多个小步骤执行,来避免了长时间的暂停。这样可以在不影响用户体验的情况下进行垃圾回收。
增量标记-整理算法的优缺点
优点:
- 避免了长时间的暂停,提高了程序的响应性。
- 增量标记-整理算法可以有效地处理循环引用问题。
缺点:
- 由于增量标记-整理算法是一种标记-整理算法,所以会产生碎片化的内存,这可能降低内存利用率。
- 增量标记-整理算法的实现需要额外的空间来存储活动对象和空闲对象。
增量标记-整理算法是基于标记-清除算法和标记-整理算法的结合体。它首先使用标记-清除算法找出所有存活的对象,然后使用标记-整理算法将这些对象移动到一起,以便进行回收。
三、性能优化措施
JavaScript 中没有强制垃圾回收的方法,也没有手动释放内存的方法, JavaScript 引擎会根据需要自动进行垃圾回收。
在 JavaScript 中,当一个对象不再被任何变量引用时,它就会被视为垃圾并被回收。需要注意的是,JavaScript 中的垃圾回收仅针对不再使用的内存,而不是不再使用的变量。例如,如果一个变量存储的是对象的引用,则该对象可能不再被其他变量引用,但仍然可能被使用。
还有一些开发人员可以采取的优化措施来提高程序的性能。例如,在不再使用的时候将变量赋值为 null 或 undefined,可以帮助 JavaScript 引擎更快地找到垃圾。
需要注意的是,JavaScript 中的垃圾回收并不能保证程序一定不会出现内存泄漏的情况,例如循环引用,开发人员需要知道这种情况并采取对应的处理措施。
总之,JavaScript 中的内存管理主要由 JavaScript 引擎负责,开发人员不需要手动管理内存。JavaScript 中的垃圾回收是自动进行的,开发人员只需要了解垃圾回收机制并采取优化措施,就可以帮助程序更好的管理内存。
JavaScript 内存管理及垃圾回收的更多相关文章
- javascript中的内存管理和垃圾回收
前面的话 不管什么程序语言,内存生命周期基本是一致的:首先,分配需要的内存:然后,使用分配到的内存:最后,释放其内存.而对于第三个步骤,何时释放内存及释放哪些变量的内存,则需要使用垃圾回收机制.本文将 ...
- C#内存管理与垃圾回收
垃圾回收还得从根说起,就像生儿育女一样. 根:根是一个位置,存放一个指针,该指针指向托管堆中的一个对象,或是一个空指针不指向任何对象,即为null.根存在线程栈或托管堆中,大部分的跟都在线程栈上,因为 ...
- 使用虚幻引擎中的C++导论(四-内存管理与垃圾回收)(终)
使用虚幻引擎中的C++导论(四)(终) 第一,这篇是我翻译的虚幻4官网的新手编程教程,原文传送门,有的翻译不太好,但大体意思差不多,请支持我O(∩_∩)O谢谢. 第二,某些细节操作,这篇文章省略了,如 ...
- Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收
很多Java面试的时候,都会问到有关Java垃圾回收的问题,提到垃圾回收肯定要涉及到JVM内存管理机制,Java语言的执行效率一直被C.C++程序员所嘲笑,其实,事实就是这样,Java在执行效率方面确 ...
- Java内存管理和垃圾回收
笔记,深入理解java虚拟机 Java运行时内存区域 程序计数器,线程独占,当前线程所执行的字节码的行号指示器,每个线程需要记录下执行到哪儿了,下次调度的时候可以继续执行,这个区是唯一不会发生oom的 ...
- 面试题之C# 内存管理与垃圾回收
面试题之C# 内存管理与垃圾回收 你说说C# 的内存管理是怎么样的 这句话我记了一个多礼拜了, 自从上次东北师大面试之后, 具体请看<随便扯扯东北师大的面试>. 国庆闲着没事, 就大概了解 ...
- JVM内存管理及垃圾回收【转】
很多Java面试的时候,都会问到有关Java垃圾回收的问题,提到垃圾回收肯定要涉及到JVM内存管理机制,Java语言的执行效率一直被C.C++程序员所嘲笑,其实,事实就是这样,Java在执行效率方面确 ...
- .NET基础 (05)内存管理和垃圾回收
内存管理和垃圾回收1 简述.NET中堆栈和堆的特点和差异2 执行string abc="aaa"+"bbb"+"ccc"共分配了多少内存3 ...
- JVM原理(Java代码编译和执行的整个过程+JVM内存管理及垃圾回收机制)
转载注明出处: http://blog.csdn.net/cutesource/article/details/5904501 JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.e ...
- java Vamei快速教程22 内存管理和垃圾回收
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 整个教程中已经不时的出现一些内存管理和垃圾回收的相关知识.这里进行一个小小的总结. ...
随机推荐
- 【MySQL】01_运算符、函数
运算符 运算符是保留字或主要用于 SQL 语句的 WHERE 子句 中的字符,用于执行操作,例如:比较和算术运算. 这些运算符用于指定 SQL 语句中的条件,并用作语句中多个条件的连词. 常见运算符有 ...
- dns隧道攻击原理及常用工具流量分析
DNS协议是一种请求应答协议,也是一种可用于应用层的隧道技术.虽然DNS流量的异常变化可能会被发现,但是在基于传统socket隧道已经濒临淘汰,TCP.UDP通信大量被安全设备拦截的大背景下,DNS. ...
- 如何在.NET程序崩溃时自动创建Dump?
今天在浏览张队转载文章的留言时,遇到一个读者问了这样的问题,如下图所示: 首先能明确的一点是"程序崩溃退出了是不能用常规的方式dump的",因为整个进程树都已经退出.现场已经无法使 ...
- ES6 学习笔记(九)Set的基本用法
1 基本用法 set类似于数组,它的成员是唯一的,当有多个相同的值,只会保留一份. 1.1 创建方法 Set本身是一个构造函数,用来生成Set实例,如: const s = new Set() let ...
- 修改Oracle共享池大小
1. sysdba登录数据库 [oracle@ufdb165 ~]$ sqlplus /nolog SQL*Plus: Release 11.2.0.4.0 Production on Wed Au ...
- 第2-3-2章 环境搭建-文件存储服务系统-nginx/fastDFS/minio/阿里云oss/七牛云oss
目录 5. 文件服务开发 5.1 环境搭建 5.1.1 数据库环境搭建 5.1.2 Nacos环境搭建 5.1.3 Nginx环境搭建 5.1.4 maven工程环境搭建 5. 文件服务开发 全套代码 ...
- 自学 TypeScript 第三天 使用webpack打包 TS 代码
前言: 大家好啊,昨天介绍了 TS 编译器的配置,但在我们实际开发当中直接使用 TS 编译器去编译代码的情况会有,但没有很多,因为我们在开发大型项目的时候,一般我们都会用到打包工具,也不可能脱离打包工 ...
- 自学 TypeScript 第四天,手把手项目搭建
前言: 学了三天,我们学习了 TS 的基本类型声明,TS 的编译,webpack 打包,其实也就差不多了,剩下的也就一些 类,继承,构造函数,抽象类,泛型一些的,如果都细致的讲可能写好久,感兴趣的可以 ...
- ARM MMU架构 -- CPU如何访问MMU及DRAM
<ARM Architecture Reference Manual ARMv8-A>里面有Memory层级框架图,从中可以看出L1.L2.DRAM.Disk.MMU之间的关系,以及他们在 ...
- MySQL数据库:6、约束的概述及语法
Python基础之MySQL数据库 目录 Python基础之MySQL数据库 一.约束概述 1.为什么要约束 2.什么是约束 3.约束的分类 4.查看当前表已有的约束 二.约束语法及用法 1.无符号 ...