当前位置: 首页 > news >正文

JavaScript原生之垃圾回收原理、标记清理原理

欢迎学习C语言和Self语言一夜情的产物:JavaScript

JavaScript(通常缩写为JS)是一种解释性脚本语言(代码不进行预编译),主要用来向HTML页面添加交互行为。它已经由ECMA(欧洲电脑制造商协会)通过ECMAScript实现语言的标准化。它被世界上的绝大多数网站所使用,也被世界主流浏览器(Chrome、IE、Firefox、Safari、Opera)支持。

1995年,Brendan Eich进入网景公司,在公司"看上去与Java足够相似",但是比Java简单,使得非专业的网页作者也能很快上手”的要求下,用10天确定了设计思路并为其浏览器开发了js功能,以下为设计思路:

(1)借鉴C语言的基本语法;

(2)借鉴Java语言的数据类型和内存管理;

(3)借鉴Scheme语言,将函数提升到"第一等公民"(first class)的地位;

(4)借鉴Self语言,使用基于原型(prototype)的继承机制。

值得一提的是,Brendan本人并不喜欢自己的这个作品,虽然当时很多人都十分喜欢Java语言,但Brendan却不是其中一员,因此即使JavaScript在后来成为互联网第一大语言,全世界有几百万学习者,但Brendan仍然不喜这个以Java为设计原型的作品,他将其称为“C语言和Self语言一夜情的产物”。

垃圾回收

JavaScript是使用垃圾回收的语言,也就是说执行环境负责在代码执行时管理内存。在C和C++等语言中,跟踪内存使用对开发者来说是一个很大的负担,也是很多问题的来源。JavaScript为开发者卸下了这个负担,通过自动内存管理实现内存分配和闲置资源回收。基本思路很简单:确定哪个变量不会再使用,然后释放它占用的内存。这个过程是周期性的,及垃圾回收每个一段时间(或者说再代码执行过程中某个预定的收集时间)就会自动运行。垃圾回收过程是一个近似且不完美的方案,因为某块内存是否有用,属于”不可判定的“问题,意味着靠算法是解决不了的。

我们以函数中局部变量的正常生命周期为例。函数中的变量会在函数执行时存在。此时,栈(或堆)内存会分配空间以保存相应的值。函数在内部使用了变量,然后退出。此时,就不再需要那个局部变量了,它占用的内存可以释放,供后面使用。这种情况下显然不再需要局部变量了,但并不是所有时候都会这么明显。垃圾回收过程必须跟踪记录哪个变量还会使用,以及哪个变量不会再使用,以便回收内存。如何标记未使用的变量也许由不同的实现方式。不过,在浏览器的发展史上,用到过两种主要的标记策略:标记清理和引用计数。

标记清理

JavaScript最常用的垃圾回收策略时标记清理。当变量进入上下文,比如在函数内部声明一个变量时,这个变量会被加上存在上下文中的标记。而上下文中的变量,逻辑上讲,永远不应该释放他们的内存,因为只要上下文中的代码在运行,就有可能用到他们。当变量离开上下文时,也会被加上离开上下文的标记。

给变量加标记的方式有很多。比如:当变量进入上下文时,反转某一位;或者可以维护”上下文中“和”不在上下文中“两个变量列表,可以把变量从一个列表转移到另一个列表。标记过程的实现并不重要,关键是策略。

垃圾回收程序运行的时候,会标记内存中的存储的所有变量(记住,标记方法有很多种)。然后,它会将所有在上下文中的变量,以及被在上下文的变量引用的变量的标记去掉。在此之后在被加上标记的变量就是待删除的了,原因是任何在上下文中的变量都访问不到他们了。随后垃圾回收程序做一次内存清理,销毁带标记的所有值并收回他们的内存!

 

 

相关文章:

  • python解CCF-CSP真题《202209-2 何以包邮?》
  • 【面试必刷TOP101】面试官:如何删除有序链表中重复的元素?
  • U3DVR向量点乘与叉乘概念及几何模型公式应用
  • stm32串口发送数据包进行解析,实现人机交互
  • 【Django框架】——02 Django虚拟环境搭建
  • 【从零带你玩转Linux】目录文件相关操作指令
  • k8s-资源管理
  • 版本控制工具 之 Git
  • 机器学习笔记 - 使用 Pix2Pix 进行图像翻译
  • 【一起学数据结构与算法】深度学习栈
  • RHCSA知识点汇总
  • Python程序员,你还在用selenium吗?试试Playwright吧
  • STM32Fxx位带操作还不会?哲学三问让你实现位带自由(含位带操作核心代码)以LED与键盘为例
  • 大厂笔试面试总汇目录
  • ESP32 LVGL8.1 M5 Core2 + LVGL + IDF 详细的移植教程 (30)
  • 【159天】尚学堂高琪Java300集视频精华笔记(128)
  • 【MySQL经典案例分析】 Waiting for table metadata lock
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • HomeBrew常规使用教程
  • js数组之filter
  • JS字符串转数字方法总结
  • PHP CLI应用的调试原理
  • Python学习笔记 字符串拼接
  • socket.io+express实现聊天室的思考(三)
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 猴子数据域名防封接口降低小说被封的风险
  • 将 Measurements 和 Units 应用到物理学
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 力扣(LeetCode)21
  • 推荐一个React的管理后台框架
  • 一起来学SpringBoot | 第十篇:使用Spring Cache集成Redis
  • 优秀架构师必须掌握的架构思维
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • 树莓派用上kodexplorer也能玩成私有网盘
  • 移动端高清、多屏适配方案
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • #include
  • (30)数组元素和与数字和的绝对差
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (ctrl.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“
  • (转) 深度模型优化性能 调参
  • (转)Sublime Text3配置Lua运行环境
  • .gitignore文件---让git自动忽略指定文件
  • .Net - 类的介绍
  • .NET Core工程编译事件$(TargetDir)变量为空引发的思考
  • .net wcf memory gates checking failed
  • .net6使用Sejil可视化日志
  • .Net环境下的缓存技术介绍
  • .NET牛人应该知道些什么(2):中级.NET开发人员
  • .net中的Queue和Stack
  • @在php中起什么作用?
  • [1127]图形打印 sdutOJ
  • [2015][note]基于薄向列液晶层的可调谐THz fishnet超材料快速开关——
  • [Android] Android ActivityManager