JavaScript中的堆栈以及垃圾回收机制

先思考一下:

 //以下的结果是什么?
 {}=={} 
 []==[]
 ''==''

堆(heap)与栈(stack)

在JavaScript中简单数据类型是放在栈中的,复杂数据类型是放在堆中的。
基本类型:这些类型在内存中分别占有固定大小的空间,他们的值保存在栈空间,我们通过按值来访问的
引用类型:引用类型,值大小不固定,栈内存中存放地址指向堆内存中的对象。是按引用访问的。

区别

栈(stack)会自动分配内存空间,会自动释放。堆(heap)动态分配的内存,大小不定也不会自动释放。
:队列优先,先进先出;由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。
:先进后出;动态分配的空间 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。

传值和传址

本类型与引用类型最大的区别实际就是传值与传址的区别。

  • 从一个向另一个变量复制 引用类型 的值,复制的其实是指针(也就是栈中地址,这个地址指向堆中的对象),因此两个变量最终指向堆中的同一个对象。即复制的是栈中的地址而不是堆中的对象。
  • 从一个变量复向另一个变量复制基本类型的值,会创建这个值的副本。也就是会在栈中重新开辟一个新的内存空间,并给它赋值

举例:

<script>
	var a=4;
	var b=a;
	a=10;
	console.log(a,b); //结果:10,4
</script>

基本类型是放到栈中的,首先是在栈中为,开辟一个内存空间存放4并赋值给a,然后再为开辟一个内存空间也存放4并赋值给b,然后修改a的值为10,因为a,b的内存地址不一样,所以互不影响。
图解:(图片没处理,可以先下载然后放大看)
在这里插入图片描述


var obj = {
	a:1,
	b:2
}
var obj1 = obj;
console.log(obj1,obj);
obj.a = 20;
console.log(obj);//修改了obj的值,obj1的值也改变了
obj1.b = 30;
console.log(obj);

复杂类型是放到堆中的。
看图解,更加清晰易懂!!(下载先放大看吧嘻嘻!)

在这里插入图片描述


关于复杂数据类型赋值的方式图解

也凑合下载放大看吧!

在这里插入图片描述

堆栈溢出

上边说道栈的数据会自动清除,而堆中的数据不会自动清除,需要手动清除。

每次存储数据,就会造成堆中的东西一直在增加,也就是当存储的数据达到某一限制时,就会造成堆栈溢出。

内存泄漏

当不断的向堆中存储数据,而不进行清理,这就是内存泄漏。(内存泄漏的结果就是堆栈溢出

垃圾回收机制

为了不让内存泄漏,清理的方式就叫【垃圾回收机制】,(栈中不用的就自动清理,而堆不能)
一般分为两种:一种是自动清理,一种是手动清理(gc机制)。js中只有自动清理。清理的对象也可以叫做 ‘孤儿对象’ 。(堆中的数据的地址在栈中没有任何引用,这个堆中的数据对象就叫孤儿对象)

垃圾回收机制:就是将引用堆中地址的对象设置为null,并且将所有引用该地址的对象都设置为null,但是不会即时清除,因为垃圾回收车会根据内存的情况在适当的时候清除堆中的’孤儿对象’(也就是这个对象没有任何引用)

例如: 对上边的例子进行垃圾回收

设置 obj=null; 在栈中把obj的值设置为null,此时obj就没有引用堆中的数据对象,但是不会把堆中的数据对象清除掉,因为obj1还在引用它,所以堆中的数据对象,还不是"孤儿",只有把obj1也设置为null,垃圾回收车才会在适当的时机把堆中的数据孤儿清理掉。

总结:如果想要清除复杂数据类型,也就是堆中的数据,必须将所有引用堆中地址的对象设置为null

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值