JavaScript之浅谈内存空间
JavaScript之浅谈内存空间
JavaScipt 内存自动回收机制
在JavaScript中,最独特的一个特点就是拥有自动的垃圾回收机制(周期性执行),这也就意味者,前端开发人员能够专注于业余,从而减少在内存的管理,提高开发的效率。
用户自定义的对象、函数,但这些都是我们肉眼不可见的,而是依靠在外部的媒介“内存条”中,自动垃圾回收的本质也就是找出已不再使用的变量、函数,释放其占用的内存空间
当不再需要某样东西时会发生什么? JavaScript 引擎是如何发现并清理它?
可达性
JavaScript 中内存管理的主要概念是可达性。
简单地说,“可达性” 值就是那些以某种方式可访问或可用的值,它们被保证存储在内存中。
固有的可达值(根)
本地函数的局部变量和参数
当前嵌套执行上下文其他函数的变量和函数
全局变量
如果引用或者引用链可以通过根访问到任何其他值,则认为该值是可访问的
实际上网页的元素就是由一个个对象构建成了一个dom树(特殊的图结构)(树结构是单向,图结构是双向的,)

通过JavaScipt提供的api我们可以找到页面上指定元素的对象,并对其进行操作
每一个DOM元素对象都可以看作是一个根,我们可以还可以访问自身元素的亲戚
父元素
兄弟元素
祖先元素
后代元素
单项引用
var user = {
name : 'EYS',
}
这里的箭头表示一个对象引用,全局变量 "user" 引用对象{name : 'EYS'} user对象中的name属性存储了一个基本类型的数据
但如果user的值被覆盖,则引用丢失
user = null;
现在user变成不可达的状态,没有办法访问之前的值,他们之间没有联系,就被JavaScript引擎发现他了!!!然后就把他丢到小黑屋去了,自动释放了它所占用的内存空间
#### 双向引用
// user具有对象的引用
var user = {
name: "John"
};
var admin = user; //引用传递
该对象仍然可以通过 admin 全局变量访问,所以它在内存中。如果我们也覆盖admin,那么它可以被释放。
相互关联的对象
function marry (man, woman) {
woman.husban = man;
man.wife = woman;
return {
father: man,
mother: woman
}
}
let family = marry({
name: "John"
}, {
name: "Ann"
})
产生的内存结构:
内存中的图片变成:
现在让我们删除两个引用:
delete family.father;
delete family.mother.husband;
仅仅删除这两个引用中的一个是不够的,因为所有对象仍然是可访问的。
输出引用无关紧要。只有传入的对象才能使对象可访问,因此,John 现在是不可访问的,并将从内存中删除所有不可访问的数据。
垃圾回收之后:
但是如果我们把这两个都删除,那么我们可以看到 John 不再有传入的引用:
无法访问的数据块
family = null;
但是如果我们把这两个都删除,那么我们可以看到 John 不再有传入的引用:
“family”对象已经从根上断开了链接,不再有对它的引用,因此下面的整个块变得不可到达,并将被删除。
回收过程
标记清除 (推荐)
分为『进入环境』和『离开环境』
进入环境 : 指变量进入的执行环境
离开环境 : 指变量完成任务,离开了执行的环境
垃圾收集器会在脚本运行的时候给存储在内存中的所有变量都加上标记
它会去掉环境中的变量以及被环境中的变量引用的变量的标记
而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了
最后,垃圾收集器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间
引用计数 (不推荐)
含义 : 跟踪记录每个值被引用的次数
当用户声明了一个变量并将一个引用类型值赋给该变量时,则这个值的应用次数就为1 【声明变量并赋值】
如果同一个值又被赋给另一个变量,则该值的引用次数加 1 【变量的值传递】
如果包含这个值引用的变量被覆盖了,则之前的值的应用次数减1 【覆盖变量之前的值】
当这个值的引用次数变成 0 时,则说明没有办法再访问这 个值了,因而就可以将其占用的内存空间回收回来。 【变量回收】
这种机制其实在js中并不常用,因为这种机制会产生循环引用的问题,『循环引用』指的是对象 A 中包含一个指向对象 B 的指针,而对象 B 中也包含一个指向对象 A 的引用。对于像js类的自动回收机制的语言来说,需要额外手动的去释放内存,其实并不友好。
在学习内存空间之前,我们需要对三种数据结构有一个清晰的理解。他们分别是堆(heap),栈(stack)与队列(queue)。
三种数据结构
一、栈(Stack)数据结构
JavaScript中并没有严格意义上区分栈内存与堆内存
如JavaScript的执行上下文(关于执行上下文我会在下一篇文章中总结)。执行上下文的执行顺序借用了栈数据结构的存取方式(也就是后面我们会经常提到的函数调用栈)。因此理解栈数据结构的原理与特点十分重要。
JavaScript的数据类型分为两种 : 基本类型,引用类型
我们可以简单粗暴的理解 基本类型数据是存储在栈,引用类型的数据是存储在堆中,等待变量建立引用关系
要简单理解栈的存取方式,我们可以通过类比乒乓球盒子来分析。如下图左侧。

基本特征为 : 先进后出,后进先出
二、堆(Heap)数据结构
堆数据结构是一种树状结构。它的存取数据的方式,则与书架与书非常相似。
书虽然也整齐的存放在书架上,但是我们只要知道书的名字,就可以很方便的取出我们想要的书,而不用像从乒乓球盒子里取乒乓一样,非得将上面的所有乒乓球拿出来才能取到中间的某一个乒乓球。好比在JSON格式的数据中,我们存储的key-value是可以无序的,因为顺序的不同并不影响我们的使用,我们只需要关心书的名字。
三、队列
队列是一种先进先出(FIFO)的数据结构。正如排队过安检一样,排在队伍前面的人一定是最先过检的人。用以下的图示可以清楚的理解队列的原理。

JavaScript之浅谈内存空间的更多相关文章
- 【微信小程序项目实践总结】30分钟从陌生到熟悉 web app 、native app、hybrid app比较 30分钟ES6从陌生到熟悉 【原创】浅谈内存泄露 HTML5 五子棋 - JS/Canvas 游戏 meta 详解,html5 meta 标签日常设置 C#中回滚TransactionScope的使用方法和原理
[微信小程序项目实践总结]30分钟从陌生到熟悉 前言 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么做 2. 微信小程序开发06-一个业务页面的完成 3. 微信小程序开发05- ...
- Qt浅谈内存泄露(总结)
Qt浅谈内存泄露(总结) 来源 http://blog.csdn.net/taiyang1987912/article/details/29271549 一.简介 Qt内存管理机制:Qt 在内部能够维 ...
- C学习笔记(11)--- 可变参数,浅谈内存管理 【C基础概念系列完结】
1.可变参数(variable arguments): 可变参数允许您定义一个函数,能根据具体的需求接受可变数量的参数. int func(int, ... ) (函数 fun ...
- javascript数组浅谈2
上次说了数组元素的增删,的这次说说数组的一些操作方法 join()方法: ,,] arr.join("_") //1_2_3 join方法会返回一个由数组中每个值的字符串形式拼接而 ...
- javascript数组浅谈1
最近心血来潮要开始玩博客了,刚好也在看数组这块内容,第一篇就只好拿数组开刀了,自己总结的,有什么不对的地方还请批评指正,还有什么没写到的方面也可以提出来我进行完善,谢谢~~ 首先,大概说说数组的基本用 ...
- 【javascript】浅谈javaScript的深拷贝
前言: 最开始意识到深拷贝的重要性是在我使用redux的时候(react + redux), redux的机制要求在reducer中必须返回一个新的对象,而不能对原来的对象做改动,事实上,当时 ...
- JAVA NIO之浅谈内存映射文件原理与DirectMemory
JAVA类库中的NIO包相对于IO 包来说有一个新功能是内存映射文件,日常编程中并不是经常用到,但是在处理大文件时是比较理想的提高效率的手段.本文我主要想结合操作系统中(OS)相关方面的知识介绍一下原 ...
- 【NIO】NIO之浅谈内存映射文件原理与DirectMemory
Java类库中的NIO包相对于IO 包来说有一个新功能是内存映射文件,日常编程中并不是经常用到,但是在处理大文件时是比较理想的提高效率的手段.本文我主要想结合操作系统中(OS)相关方面的知识介绍一下原 ...
- JavaScript闭包浅谈
------------------- 作者:willingtolove: 本文链接:http://www.cnblogs.com/willingtolove/p/4745889.html 1. 变量 ...
随机推荐
- Python python对象 enumerate
""" enumerate(iterable[, start]) -> iterator for index, value of iterable Return a ...
- .NET 5.0 Preview 2发布
2020年4月2日微软.NET 团队的项目经理 Richard 在博客上 发布了.NET 5 Preview 2:https://devblogs.microsoft.com/dotnet/annou ...
- [vijos1460&Metocode P223]拉力赛<LCA>
题目链接:https://vijos.org/p/1460 http://oj.fjaxyz.com:3389/problem.php?id=223 我不禁开始怀疑,这,真的是最近公共祖先的题吗,我是 ...
- Java实验五参考答案
1.找错误 btOK.setOnAction( new EventHandler<ActionEvent> { public void handle (ActionEvent e) { S ...
- Vue设置路由跳转的两种方法: <router-link :to="..."> 和router.push(...)
一.<router-link :to="..."> to里的值可以是一个字符串路径,或者一个描述地址的对象.例如: // 字符串 <router-link to= ...
- js 数组 随机排序
方法一: function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1) + min) } fu ...
- PTA数据结构与算法题目集(中文) 7-23
PTA数据结构与算法题目集(中文) 7-23 7-23 还原二叉树 (25 分) 给定一棵二叉树的先序遍历序列和中序遍历序列,要求计算该二叉树的高度. 输入格式: 输入首先给出正整数N(≤50) ...
- Halo博客的搭建
今日主题:搭建一个私人博客 好多朋友和我说,能不能弄一个简单的私人博客啊,我说行吧,今天给你们一份福利啦! 搭建一个私人博客,就可以在自己的电脑上写博客了 Halo Halo 是一款现代化的个人独立博 ...
- alembic的常用参数
alembic的常用参数 命令和参数解释 1 .init:创建一个alembic仓库. 2 .revision:创建一个新的版本文件. 3 .--autogenerate:自动将当前的模型修改,生成迁 ...
- MTK Android 如何获取系统权限
Android如何获得系统(system)权限 Android中如何修改系统时间(应用程序获得系统权限) 在 android 的API中有提供 SystemClock.setCurrentTimeMi ...