我们的v8引擎中的内存是如何分配的,他分为新生代和老生代,新生代是那种调用次数较少的对象,老生代里面存放的就是我们多次调用的对象。如下图所示:

新生代空间(New Space /Young Generation)
主要放的是我们生命周期短的小对象,频繁的销毁和创建。新生代分为两个半空间From Space和To Space。初始的时候我们先分别内存到From Space,当其中的某个小对象被销毁的时候,就会使用复制算法,将From Space中的小对象复制到To Space,当内存中又有新的小对象生成的时候,就会先增加再调用复制算法,就是先将To Space里面增加这个小对象,然后复制给From Space对象。同时使用标记算法,记录调用次数,当调用次数大于二或多次调用就会将该对象放到老生代。这里我们要知道From Space和To Space会一直进行角色互换。
老生代空间(Old Space /Old Generation)
老生代空间里面放的就是存放生命周期长或从新生代晋升过来的对象。当我们的对象在新生代调用两次以上就会自动升级到老生代。
这里主要分为两个区域:
老指针空间(OldPointer Space)
主要存放包含其他对象的指针对象。
老数据空间(OldData Space)
存放的就是原始数据(字符串,数字),不含其他对象的指针。
大对象空间(Large Object Space)
存放大对象,就是超过新生代存放大小的数组或对象。这些对象直接在大对象空间中分配,避免在新生代和老生代之间的复制操作
代码空间(Code Space)
存放编译后的函数代码
单元空间(Cell Space)
用于存放小的数据结构,比如闭包的变量环境。
属性单元空间(Property Cell Space)
存放对象的属性值,主要针对全局变量或者属性值,对于访问频繁的全局变量或者属性值来说,V8在这里存储是为了提高它的访问效率。
映射空间(Map Space)
存放对象的映射(即对象的类型信息,描述对象的结构)。
当你定义一个Person 构造函数时,可以通过它创建出来person1和person2。这些实例(person1 和person2)本身存储在堆内存的相应空间中,具体是新生代还是老生代取决于它们的生命周期和大小。每个实例都会持有一个指向其映射的指针,这个映射指明了如何访问name 和age 属性
堆内存(Heap Memory)与栈(Stack)
堆内存:JavaScript 对象、字符串等数据存放的区域,按照上述分类进行管理。
栈:用于存放执行上下文中的变量、函数调用的返回地址(继续执行哪里的代码)等,栈有助于跟踪函数调用的顺序和局部变量。
补充
什么是垃圾回收机制,他是如何帮助我们管理内存的?
随着硬件的发展,我们电脑内存的容量越来越大,但是也有内存不够用的情况。因此内存管理是非常有必要的。垃圾回收机制在我们现代化的编程语言中通常帮助我们自动回收来防止内存泄漏,增加代码运行效率。
在运行时,垃圾回收通常监听每个函数的生命周期来工作,当垃该函数不被调用的时候就视为垃圾。一旦这些标记为垃圾的对象被识别,垃圾回收机制就将他们销毁,从而腾出更多内存来为新的对象使用。
垃圾回收机制一般使用垃圾回收算法,一般使用:循环计数,标记清除,标记整理。
循环计数
就是将我们调用的对象关联计数器,程序每被调用一次,关联计数器就+1,当我们的对象关联计数器大于二的时候一般就会被程序转换为机器码,提高运行效率。当我们对象的关联计数器为0的时候,循环计数算法就会将该对象销毁。腾出更多空间给新对象使用。
标记清除
标记清除算法就是,从第一个对象开始,标记每个对象的可达性,如果当前的对象没被标记就会被清除。
标记整理
标记整理算法就是在标记清除之后,内存空间是不连续的,为了更高的利用内存空间,通常会将不连续的空间通过标记整理算法来减少内存碎片,增加内存的利用效率。
V8引擎的垃圾回收机制具体是如何工作的?
V8引擎使用了一种高度优化的垃圾回收机制来管理内存采用了标记:清除、标记整理,同时又结合了多种策略来实现高效的内存管理,包括结合了分代回收(Generational Collection)和增量回收(Incremental Collection)等多种策路。
分代回收:V8将对象分为“新生代"和"老生代"。新生代存放生命周期短的小对象,使用高效的复制式垃圾回收算法;而老生代存放生命周期长或从新生代晋升而来的对象,使用标记-清除或标记·整理算法。这种分代策略减少了垃圾回收的总体开销,尤其是针对短命对象的快速回收。
增量回收:为了减少垃圾回收过程中的停顿时间,V8实现了增量回收。这意味着垃圾回收过程被分解为许多小步骤,这些小步骤穿插在应用程序的执行过程中进行。这有助于避免长时间的停顿,改善了应用程序的响应性和性能。
延迟清理和空闲时间收集:V8还尝试在CPU空闲时进行垃圾回收,以进一步减少对程序执行的影响。
这些技术的结合使得V8能够在执行lavaScript代码时有效地管理内存,同时最小化垃圾回收对性能的影响
感谢大家观看
@秋风于渭水 确实
[...]不同的浏览器存在兼容性问题的核心原因是不同的浏览器可能使用的是不同的浏览器内核。在现代化开发中,大多数的浏览器兼容性问题是可以通过工程化中的配置选项来解决的。1.比如browserslist可以配置目标的浏览器或者Node环境,然后在不同的工具中起作用,比如autoprefixer/babel/postess preset env等,在进行了正确的配置后,开发的Vue或者React项目在进行打包时[...]
[...]在BFC中,box会在垂直方向上一个挨着一个的排布垂直方向的间距由margin属性决定在同一个BFC中,相邻两个box之间的margin会折叠(collapse)在BFC中,每个元素的左边缘是紧挨着包含块的左边缘的然后我们再看一下官方文档中如何说明的?总结BFC是什么?W3C文档讲:在标准流中,我们所有的盒子,不管是块级盒子还是行内盒子,它们都属于某一个FC格式化上下文,块级盒子属于BFC`块级格[...]
[...]什么是FC呢这里我们给出W3C给出的文档,FC文档FC的全称是FormattingContext,元素在标准流里面都是属于一个FC的。那么什么又是IFC,BFC呢?IFC行内元素的布局都属于Inline Formatting,inline level box都是在IFC中布局的BFCBFC英文全称是Block Formatting Context,也就是block level box都是在BFC中[...]
这确实是一个盲点,这个还是很有必要的,处理不好会导致网页内的元素出现抖动问题。
[...]我们知道,当浏览器在执行到script标签的时候,首先会停止构建DOM树,然后下载Javascript文件并且执行,当JavaScript脚本执行完毕之后才会继续解析HTML标签构建DOM树。为什么Javascript程序会这样做呢?原因是我们的Javascript的作用就是操作DOM并且可以修改DOM。如果我们等到HTML执行完成之后再去执行JavaScript就会造成严重的回流和重绘,尤其是现[...]
[...]async属性和defer属性目标一样它也是为了不让js阻塞DOM树的构建。不过他们两个还是有区别的。async让js脚本的下载和执行是独立的。浏览器不会因为async属性的script脚本的执行而阻塞,这一点和defer属性类似。然而async属性比较任性,只要脚本被浏览器下载完成之后就会立即执行,不会等待在DOMContentLoaded之前执行。所以它不能保证是在DOMContentLoad[...]
我热爱 旅游专栏。令人惊艳了解路线。
欣赏你的照片, 我明白, 世界很美。感谢 旅行灵感。
读起来像小说。继续保持 带来的灵感。