最近在学习JavaScript的相关内容,看到了关于内存的一些知识点,这里做一些笔记,以便于加深自己的理解。
计算机的内存在存储数据的时候是需要一直通电的,一旦断电就会出现内存数据丢失的情况,也就是计算机的配置中的内存条中的数据,如果想要在断电之后任然能保存数据就需要将内存中的数据拷贝到外存里面,外存就是计算机的硬盘。
现在计算机内存的大小一般是1GB、2GB、4GB、8GB、16GB、32GB、64GB,内存存储数据很快,而外存存储数据比较慢。存储数据比较快的外存是固态硬盘,存储速度接近内存的存储速度,市面上比较好的品牌有三星、金士顿、台电、影驰、东芝等,但是比较贵,也不容易坏,而一般的外存都是机械硬盘,存储的速度比较慢,容易坏,一般寿命是10年。
以下是关于内存单位的换算:
1GB=1024MB
1MB=1024KB
1KB=1024B,1B表示1字节,
1B=8b,1b表示1位,
1GB可以存储的0/1数量就是8*1024^3个
一般计算机开机之后就将操作系统读取到内存中。这里以2GB的内存为例,操作系统占到512MB,对于浏览器只要多开一些页面,就会占到1GB的内存,(对于前端开发,浏览器的使用会占用很多内存,所以一般都建议购买内存是8GB及以上的计算机),浏览器分配到的内存,会将其分别分配给HTML+CSS、JS、网络的HTTP等。假如浏览器中的JS所占的内存大概是100MB,在得到这个内存之后,有将这个内存分为两个区域,这两个区域分别是代码区和数据区,分别用来存储代码和数据的,而数据区又被分为两个区,分别是栈内存和堆内存。
在浏览器中,代码区中的代码都会先进行变量提升,意思就是将所有声明的变量提升到代码的最前面,代码区指定代码之后,数据区存储的数据类型中,Stack中可以直接存储简单数据类型,包括数值,布尔值,字符串,null,undefined和symbol,复杂数据类型,则存储在Heap中,Stack区则存储Heap区对应的地址信息,代码区进行访问复杂数据类型的时候就是通过访问Stack中的Heap地址,然后再访问Heap中存储的复杂数据类型的数据。
为什么将复杂的数据存储在Heap中呢?主要原因是复杂数据类型存储在Stack区时,当改变其中的内容的时候效率会非常低,放在Heap中就能实现快速的改变复杂数据类型的值了。
JavaScript在存储数据的时候,将会出现下面的四种基本情况
1、简单数据类型的数值的改变
这时的a = 1 没有发生改变
2、复杂数据类型的访问地址变更
这时的a.name = a ,没有发生改变
3、复杂数据类型的内容数据更改
这时的a.name = b,发生了改变
4、复杂数据类型与简单数据类型的相互转换
第四种情况再对b进行改变的时候,就不在对对象内部的内容进行变更了,而是直接改变的是Stack中的数据类型,所以这时的a的值并不变。
这里的改变中就会出现这样的一个理论,第三句代码中,浏览器从左向右依次读取代码,a.x中的a的地址仍然是第一行代码所定义的得到的地址,然后是a={n:2},就将a进行了重新的定义,整句代码最后的意思是将a的值换为新的Heap地址,然后将所有的新的地址添加到原来Heap对象数据中的键名为x的键值对中去,那么最终就是a的值已经变为了{n:2}的Heap地址了,x就是在原来的{n:1}这个对象中添加一个键名为x的元素,其value就是新的对象{n:2}的heap地址。所以访问a就是访问{n:2},此时a中是没有x的,所以访问a.x的时候就会出错,访问b.x就是访问{n:2}的Heap地址。
GC 垃圾回收
如果一个对象没有被引用,这个对象就是垃圾,它将被回收。
var fn = function(){}
document.body.onclick = fn
fn = null
这个时候的function(){}不算是垃圾,不会被回收。
从上面的分析图可以看出document也是一个对象,存储的是body的内存地址,而body也是一个对象,其存储的是onclick的地址,onclick存储的是fn的地址,这是在之前就已经存储好的,当fn的值变为了null,而对于onclick的存储内容而言是没有什么变化的。但是当document.body.onclick = null 时就会出现function是垃圾了,一般在浏览器关闭之后,没有document和fn之后,其中的body、onclick、function都变为了垃圾。但是对于IE浏览器,关闭页面之后并不会将这些数据视为垃圾进行清理,这就是IE的bug。
网友评论