JavaScript堆内存and栈内存
背景
在面试或者在技术群里经常遇到同学们讨论一个问题:Javascript的内存分配是怎么样的,什么数据放在栈内存,什么数据放在堆内存?
关于这个问题有两种说法:
- 阵营一:原始值或者说是基本类型的值保存在栈内存中,引用数据类型保存在堆内存中
- 阵营二:部分Number类型保存在栈内存中,其他数据都保存在堆内存中
我本人站第二种说法
Javascript到底是怎样分配内存的呢?今天就带大家扒一扒两种阵营的说法到底是怎么来的
阵营一:原始值保存在栈内存,引用数据类型保存在堆内存
- 知乎一篇文章(转自:博客园)
- 知乎一篇文章(翻译自:deepu.tech/memory-mana…
- 《Javascript高级程序设计》(4.4章节小结)
- 极客时间:浏览器工作原理与实践(12 | 栈空间和堆空间:数据是如何存储的?)
阵营二:部分Number类型保存在栈内存中,其他数据都保存在堆内存中
参考资料
首先要知道,JavaScript的标准ECMA-262并没有定义内存分类,其完全依赖编译器如何实现。这里我们以V8为讨论对象
根据官方博客文章Pointer Compression in V8原文,V8中的JavaScript值无论是object
, array
, number
还是string
都作为对象分配到V8 heap也就是堆内存中
这里并没有结束,虽然说全部值都保存在堆内存中,但是考虑到大部分程序需要进行整形数值的计算,V8采用标记指针技术可以将small integer直接存储在本应存储指针的位置。在32/64位系统中,都使用最后一位来标记当前位置是small integer还是指针
另外Chrome开发者文档的文章Memory terminology中也指出Number数据类型会被分为两种,31位的small integer和另外一种heap number,证明了small integerSMI存储在栈中,其他Number数据存储在堆中,同时该文章也明确指出string
存储在VM Heap也就是堆中
两篇官方文档指明了:string
类型会保存在堆中,并不是原始类型都保存在栈中。除了SMI,其他数据都保存在堆中
总结
针对阵营一的观点搜集到的文章,排除掉没有参考资料,转自其他文章这些人云亦云缺乏思考的,比较权威的就是《Javascript高级程序设计》,其中一些文章也是引自这本书的结论。这本书的结论从何得来,并没有更根源的参考依据或者更详细的论证
极客时间的课程中,作者并没有给出详细论证和更权威的参考资料,另外对于同学的问题作者也并没有给出回答
对于阵营一这个观点的疑问有:
- 字符串占用的空间并不是固定大小,但却是基本数据类型,也会保存在栈中吗?
- 并没有官方资料或者其他权威资料给与佐证
对于阵营二的观点,有V8官方博客和Chrome官方文章作为论证,同时也解答了针对阵营一的"字符串是否保存在栈中"的疑问(结论:保存在堆中)
另外阵营二的讨论中参考的知乎回答也有详细的步骤,通过开发者工具对内存进行分析进行佐证,甚至分析了V8的源码
结论个人站队阵营二的观点,有不同意见的同学,也希望能在评论区赐教!
关于堆和栈
大部分文章还有一个误区:会拿数据结构的堆来和内存堆讨论
其实堆栈的概念是用于传统系统语言C,C++等,个人认为JavaScript并没有栈的概念,如上文引用的官方博客Pointer Compression in V8或者Orinoco: young generation garbage collection中说明,JavaScript的对象都保存在VM Heap中,官方博文也并没有出现过栈内存的概念。只是由于V8大部分使用C++进行开发,可以理解为JavaScript的指针数据会保存在C++的栈内存中,所以会有针对JavaScript的堆栈内存的讨论
栈Stack是向下增长一块内存区域,栈区同数据结构的栈相同先进后出。栈区空间较小分配效率高,系统会自动进行分配和空间回收
堆Heap和数据结构的堆就没有关系了,堆被用于动态内存分配。程序开发者使用malloc
或new
申请任意大小的内存,用free
或delete
释放内存。动态内存的生存期可以由我们决定。堆是一块向上增长的内存区域。V8中的堆被分为新生代区和老生代区等,这个是垃圾回收的问题,不在本文讨论
感悟
这篇文章主要是希望能给大家提供一个辩证看待问题的思路,在对待深层次的理论问题,能去多考究官方权威资料,而不是人云亦云。虽然这种问题属于面试造火箭的范畴,实际工作中几乎用不到,但是在面试中如果不仅能给出一个问题的答案,而且能回答出研究问题的思路,体现出对待问题认真深入的态度,也能给面试官留下一个好印象,为面试加分
最后,希望大家能从本篇文章中有所收获,欢迎有不同思路意见的大佬评论区留言讨论!
转载自:https://juejin.cn/post/7195231830272901179