javascript - 内存空间
也许很多人像我一样,觉得JS有垃圾回收机制,内存就可以不管了,以至于在全局作用域下定义了很多变量,自以为JS会自动回收,直到最近,看了阮一峰老师,关于javascript内存泄漏的文章时,才发现自己写的代码,存在很严重的内存泄漏问题,再者,因为忽略对内存的学习,导致后面很多进阶概念很模糊,比如深复制与浅复制的区别,比如闭包、作用域链等等。
堆与栈
与C/C++不同,JavaScript语言没有严格意义上,区分堆与栈,所以我们可以理解为,JavaScript所有的数据都是存放在堆内存中。
不过,在某些场景下,我们仍然需要借助堆栈数据结构来处理,所以有必要理解一下这两个数据结构的区别。
栈:也叫做堆栈
栈数据结构的一个特点就是后进先出,好比羽毛球盒子,在一头放羽毛球,在另外一头取羽毛球。
堆数据结构,好比书架上的书,虽然已经按顺序放好了,但是我们只要知道书的名字,就可以对应的取下来,类似于JSON对象中的key-value。
变量对象与基本数据类型
JavaScript中的数据类型大致分为,基本数据类型与引用数据类型,上文提到,JavaScript中所有的数据都是存放在堆内存中,但是,这里提到的变量对象(在执行上下文创建阶段生成),由于它有特殊的职能,所以在理解上就把它与堆内存单独分开了,如下图所示:

一般变量对象里面存放的是基本数据类型,包括Undefined、Null、Boolean、Number、String,它们到是按值访问的。
demo01
var a = 20;
var b = a;
b = 30;
console.log(a);//20
上面这段代码指的是,在变量对象中执行数据复制的时候,其实系统会自动为新的变量分配一个新的值,所以a与b其实已经是完全独立的两个变量,只是值一样而已。

堆内存与引用数据类型
javascript中的引用数据类型是存放在堆内存中的,但是不同于变量对象,javascript是不允许直接访问堆内存中的数据,所以如果我们要访问引用数据类型的时候,采用的是按引用访问,其实就是在变量对象中存放了一个指向对象的句柄,可以理解为一个地址,要访问堆内存中的对象,就要通过这个引用句柄来访问,例如上图中的d变量,就是一个指向对象的地址。
demo02
var m = { a:10,b:20};
var n = m;
n.a = 15;
console.log(m.a);//15
上面这段代码指的是执行引用类型数据的复制时,在变量对象中会分配一个新的值,来存放新的变量,但是这两个变量的地址是一样的,相当于指向的对象是一样的,所以各自改变对象里面的属性值,会互相影响,如下图

内存泄漏
上面讲解了JavaScript中的内存空间,接下来就要讲解,我写这篇文章的初衷,就是我代码中严重的内存泄漏
内存泄漏:就是不再用到的内存,但是没有及时释放,就叫做内存泄漏
有些语言必须手动释放内存,程序员负责内存的管理,例如C语言
char *buffer;
buffer = (char*) malloc(42);
//do something with buffer
free(buffer);
这里malloc就是负责分配内存,free是负责释放内存。
那么JavaScript中的垃圾回收机制又是怎么一回事呢?
垃圾回收机制
以前我一直天真的以为,垃圾回收机制就像人工智能一样,会自动帮你识别出不用的内存,然后释放掉,然而真相只有一个
垃圾回收机制的原理就是,使用引用计数法,就是语言引擎有一张“引用表”,保存了内存里面所有的资源的引用次数,就像下面这样

但是如果一个值不再需要了,引用数却不为0,垃圾回收机制是无法释放这块内存,从而导致``内存泄漏例如:
const arr = [1,2,3,4,5];
console.log('hello world");
arr的引用次数为1,尽管后面不再使用arr了,但是它还会持续占用内存,所以一般要这样处理
const arr = [1,2,3,4,5];
console.log('hello world");
arr = null;
```
让arr的指向为空,垃圾回收机制就会默认它的引用数为0而回收掉。
避免内存泄漏
在局部作用域中,等函数执行完毕,变量就没有存在的必要了,js垃圾回收机制很快做出判断并且回收,但是对于全局变量,很难判断什么时候不用,所以,经验之谈就是,尽量少使用全局变量。
我们在使用闭包的时候,就会造成严重的内存泄漏,因为闭包的原因,局部变量会一直保存在内存中,所以在使用闭包的时候,要多加小心。
参考: https://www.cnblogs.com/mcray/p/7002089.html
javascript - 内存空间的更多相关文章
- 干货 | JavaScript内存空间详解
JS栈内存与堆内存 var a = 20; var b = 'abc'; var c = true; var d = { m: 20 } 因为JavaScript具有自动垃圾回收机制,所以对于前端开发 ...
- JS 从内存空间谈到垃圾回收机制
壹 ❀ 引 从事计算机相关技术工作的同学,对于内存空间相关概念多少有所耳闻,毕竟像我这种非计算机科班出身的人,对于栈堆,垃圾回收都能简单说道几句:当我明白JS 基本类型与引用类型数据存储方式不同,才 ...
- (复杂值vs原始值)&&内存空间 — 准确我们的JavaScript世界观(一):
写在前面 最近在读<JavaScript启示录>,这本书不是JavaScript的详尽的参考指南,但是把对象作为了解JavaScript的透镜,受益匪浅. 那么我们先来聊一下JavaScr ...
- 【进阶1-3期】JavaScript深入之内存空间详细图解(转)
这是我在公众号(高级前端进阶)看到的文章,现在做笔记 https://mp.weixin.qq.com/s/x4ZOYysb9XdT1grJbBMVkg 今天介绍的是JS内存空间,了解内存空间中的堆和 ...
- JavaScript之浅谈内存空间
JavaScript之浅谈内存空间 JavaScipt 内存自动回收机制 在JavaScript中,最独特的一个特点就是拥有自动的垃圾回收机制(周期性执行),这也就意味者,前端开发人员能够专注于业余, ...
- JavaScript内存优化
JavaScript内存优化 相对C/C++ 而言,我们所用的JavaScript 在内存这一方面的处理已经让我们在开发中更注重业务逻辑的编写.但是随着业务的不断复杂化,单页面应用.移动HTML5 应 ...
- [原创作品]Javascript内存管理机制
如果你也喜欢分享,欢迎加入我们:QQ group:164858883 内存策略:堆内存和栈内存栈内存:在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个 ...
- JavaScript 内存
JavaScript 中对内存的一些了解 在使用JavaScript进行开发的过程中,了解JavaScript内存机制有助于开发人员能够清晰的认识到自己写的代码在执行的过程中发生过什么,也能够提高项目 ...
- javascript内存管理(堆和栈)和javascript运行机制
内存基本概念 内存的生命周期: 1.分配所需的内存 2.内存的读与写 3.不需要时将其释放 所有语言的内存生命周期都基本一致,不同的是最后一步在低级语言中很清晰,但是在像JavaScript 等高级语 ...
随机推荐
- router.go,router.push,router.replace的区别
除了使用 <router-link> 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现.当你点击 <router-link> 时,这个 ...
- 常用linux命令行
1.ls命令 ls -a 列出目录所有文件,包含以.开始的隐藏文件 ls -A 列出除.及..的其它文件 ls -r 反序排列 ls -t 以文件修改时间排序 ls -S 以文件大小排序 ls -h ...
- java之异常统一处理
spring-mvc.xml <!-- aop --> <aop:aspectj-autoproxy/> <beans:bean id="controllerA ...
- 自写Jquery插件 Datagrid
原创文章,转载请注明出处,谢谢!https://www.cnblogs.com/GaoAnLee/p/9086582.html 废话不多说,先上个整体效果: html <div id='data ...
- webform 使用富文本编辑器
<div class="form-group"> <label class="col-xs-2 control-label text-right&quo ...
- 数据库的增、删、改、查 (CURD)
增改查删可以用CURD来表示 增加:create 修改:update 查找:read 删除:delete 增加create : insert +表名+values+(信息): in ...
- Python-OpenCV基本操作cv2
1.图片加载.显示和保存 import cv2 # 生成图片 img = cv2.imread("1.jpg") # 生成灰色图片 imgGrey = cv2.imread(&qu ...
- redis-3.2 集群
目录 简介 集群简介 Redis 集群的数据分片 Redis 集群的主从复制模型 Redis 一致性保证 redis 集群间的通信 环境 安装Ruby 部署 安装Redis略 创建集群 集群节点信息 ...
- 【题解】Luogu P2147 [SDOI2008]洞穴勘测
原题传送门 这题用Link-Cut-Tree解决,Link-Cut-Tree详解 我不太会踩爆Link-Cut-Tree的并查集做法qaq 我们用Link-Cut-Tree维护连通性(十分无脑) Co ...
- Getting started with Kaggle -- Kaggle Competitions
1: The Competition We'll be learning how to generate a submission for a Kaggle competition. Kaggle i ...