栈内存和堆内存浅析

简介: 栈内存与堆内存 对于 JS 不同类型的数据来说,基本数据类型(string/number/boolean/undefined/null)的值存储在栈内存中,引用数据类型(object)的值存储在堆内存

栈内存与堆内存

对于 JS 不同类型的数据来说,基本数据类型(string/number/boolean/undefined/null)的值存储在栈内存中,引用数据类型(object)的值存储在堆内存中,程序代码存储在文本段中。(以上只是简单理解,并不尽然,不同引擎的实现和优化并不相同)

注意,前面的用词 「的值」 ,比如 a = { id: 1 } ,存储在堆内存中的是对象 { id: 1 } ,而 变量标识符 a 则存储在栈内存中。

即,栈中存储的是 a=0x0f00000,堆中的地址 0x0f00000 存储的是 { id: 1 }

注意:对象中如果有的 key 对应的 value 是基本类型,如 string ,它也是存在堆中的。

什么是垃圾

要说垃圾回收,首先要理解哪些内存是垃圾,有用的内存什么时候变成的垃圾。

function fn() {
  let a = { id: 1 };
}
fn();

我们知道,函数调用存储于栈内存中,由系统(运行时环境)自动分配和回收内存。因此,对于函数 fn,它执行于栈内存中。

函数中的局部变量也存储在栈内存中,于是,变量标识符 a 和它的内容也存储在栈内存中。

然而,a 的内容(值)是一个引用数据类型,它会被存储到堆内存中,而把内存虚拟地址当做值赋给 a

当函数执行结束后,根据栈内存管理规则,该函数的执行环境会被从栈内存顶部弹出,于是 a=0x0f00000 被从栈内存清除,接着 fn 从栈内存清除。

至此程序执行完毕(我们假设该进程还未退出),此时栈内存是干净的(可以理解为里面的东西用完就扔),但是堆内存中 0x0f00000 位置上还存着一个对象,这个对象在之后的程序中永远都不会被访问到,因为这个对象在堆中分配内存时,只把地址告诉了 fn 中的 a,而 a 是函数的局部变量,它并未在 fn 的执行周期中把这个堆地址传给外面,于是 fn 执行完毕后就被永久性清除了,也就是说世界上再也没有人知道 { id: 1 } 这个数据住在哪里,那么这个对象对于当前执行的程序来说,就是没有意义的,但是却占用了程序内存空间,于是被看做了垃圾。

动图展示垃圾回收过程

参考资料

  1. 为什么闭包不会被垃圾回收清除
相关文章
|
3月前
|
监控 Java
压力测试Jmeter的简单使用,性能监控-堆内存与垃圾回收 -jvisualvm的使用
这篇文章介绍了如何使用JMeter进行压力测试,包括测试前的配置、测试执行和结果查看。同时,还探讨了性能监控工具jconsole和jvisualvm的使用,特别是jvisualvm,它可以监控内存泄露、跟踪垃圾回收、执行时内存和CPU分析以及线程分析等,文章还提供了使用这些工具的详细步骤和说明。
压力测试Jmeter的简单使用,性能监控-堆内存与垃圾回收 -jvisualvm的使用
|
28天前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
54 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
2月前
|
缓存 Java 测试技术
谷粒商城笔记+踩坑(11)——性能压测和调优,JMeter压力测试+jvisualvm监控性能+资源动静分离+修改堆内存
使用JMeter对项目各个接口进行压力测试,并对前端进行动静分离优化,优化三级分类查询接口的性能
谷粒商城笔记+踩坑(11)——性能压测和调优,JMeter压力测试+jvisualvm监控性能+资源动静分离+修改堆内存
|
1月前
|
C++
析构造函数就是为了释放内存,就是在局部指针消失前释放内存,拷贝构造函数就是以构造函数为模块,在堆里面新开一块,同一个变量在堆里面的地址
本文讨论了C++中构造函数和析构函数的作用,特别是它们在管理动态内存分配和释放中的重要性,以及如何正确地实现拷贝构造函数以避免内存泄漏。
36 2
|
30天前
|
算法 Java
JVM进阶调优系列(3)堆内存的对象什么时候被回收?
堆对象的生命周期是咋样的?什么时候被回收,回收前又如何流转?具体又是被如何回收?今天重点讲对象GC,看完这篇就全都明白了。
|
3月前
|
存储 程序员 编译器
堆和栈内存的区别是什么
【8月更文挑战第23天】堆和栈内存的区别是什么
229 4
|
3月前
|
存储 安全 Java
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程是什么,JDK、JRE、JVM的联系与区别;什么是程序计数器,堆,虚拟机栈,栈内存溢出,堆栈的区别是什么,方法区,直接内存
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存
|
3月前
|
JavaScript Java 开发工具
Electron V8排查问题之接近堆内存限制的处理如何解决
Electron V8排查问题之接近堆内存限制的处理如何解决
196 1
|
3月前
|
搜索推荐 Java API
Electron V8排查问题之分析 node-memwatch 提供的堆内存差异信息来定位内存泄漏对象如何解决
Electron V8排查问题之分析 node-memwatch 提供的堆内存差异信息来定位内存泄漏对象如何解决
93 0
|
3月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
345 0