v8引擎垃圾回收机制-内存与结构

v8引擎内存结构

  • 内存分配:栈空间,堆空间
  • 栈空间:代码运行的环境(逻辑运行的环境
  • 堆空间:所有函数和引用类型数据存放的具体地址
  • 堆空间有哪些部分:
 1. New Space(Young generation)新生代,
    新生代内存大小为:
    新生代会将内存完全平分为两个部分:
    Semi space from, Semi space to
 2. Old Space(Old Generation) 老生代,
    
 3. Large object space 大对象内存空间(对象超过默认大小限制时,塞入Large object space,并且不受GC垃圾回收机制管理)
 4. Code space(即时编译器会把我们已经编译的代码存在Code Space,随时在栈中执行)
 5. Cell space (单元空间)
 6. Property cell space (属性单元空间)
 7. Map space (地图空间)
  • 新生代和老生代内存大小
内存跟操作系统有关,64位还是32位
64位:新生代空间为64MB,老生代空间为1400MB
32位:新生代空间为32MB,老生代空间为700MB
补充:
1.v8引擎64位总大小为1.4G(1464MB),32位为0.7G(732MB)
2.node(v14之后),v8引擎内存为2GB
  • 垃圾回收算法
1. 新生代有一种算法
  思想:Copy(复制)
  特点:短频快
  Scavenge算法:新生代互换
  运行步骤:当定义了变量,首先放到新生代(Semi space from)中,因为新生代64M一分为二,只有32M,当达到条件后,会标记Semi sapce from里的变量,判断是否被引用,然后标记是否要被清除,把不需要清除所有内容复制到(Semi space to)空间。 然后将Semi space to 空间与Semi space from互换,情况原来的Semi space from 空间。
ps:为什么要复制,因为牺牲空间来换时间。

2. 老生代有两种算法组合起来
  思想:三步走(标记,整理,清除)
  Mark-Sweep方法(标记清除)
  Mark-Compact方法(标记整理)
  运行步骤:
ps:老生代为什么不用复制,因为老生代内存有1400M,如果用Scavenge算法,那么内存需要一分为二,因为着,有700M的内存常常处于闲置状态。

  • 标记清除法
 任何引擎,都有垃圾回收机制的跟节点(GC Roots),类似于js主线程的window。
  扫描引用关系,被扫描到的变量和对象就会给予标记,被标记的内容就是有用的数据,没有扫描到的就是垃圾。
1. 广度扫描
2. 全停顿标记
3. 增量标记法 & 三色标记法
4. 引用计数
ps: 标记整理法就是在标记清除法的基础上进行整理,把非垃圾数据进行整理,整理成连续的不间断的结构,然后清除。(标记-整理-清除)
  • 增量标记法
  • 三色标记法

  • 内存需求

首先了解v8引擎最大内存为2GB
1. 大文件上传
   如果大小超过2GB,服务直接宕掉
2. webpack打包内
3. vite(多项目集群)
  • 为什么v8引擎内存最大才2G
1. 前端的不持久化,一般情况下执行完就会被回收
2. js是单线程运行的 (如果进入垃圾回收,所有的运行逻辑都会暂停 )
3. 垃圾回收机制限制(官方文档中,回收1.5G内存需要时间50ms )
  • 垃圾回收实例
function test() {
            debugger 
            var a = 1 // 基本数据类型
            var b = {} // 引用数据类型
            var c = { a: a } // 引用数据类型
            return c
            // 如果返回基本类型 例如:return 'ok', 那么直接被回收
            // 基本类型如果用参数获取返回数据,那么相当于简单复制
            // 引用数据类型如果用参数获取返回数据,相当于获得堆内存地址,最终指向的还是变量c内存地址
        }
        // 情况1
        test()
        // 情况2
        var itest = test()
        // 执行完test后,c的内存会被回收吗
        // 情况1 只是用了test方法,会被回收
        // 情况2 如果用变量接收,就不会被回收(闭包)
        /**
         * 运行过程
         * 1. 匿名作用域
         * 2. test()入栈
         * 3. 创建a变量(栈中)
         * 4. 创建b变量(栈中,堆中会开辟一个内存地址0x111)
         * 5. 创建c变量(栈中,堆中会开辟一个内存地址0x111)
         * */
  • 为什么要关注内存
1.防止页面占用内存过大,引起客户端卡顿,甚至无响应。
2.Node使用的也是v8,内存对于后端服务的性能至关重要,因为服务的持久性,后端更容易造成内存溢出  

ps:v8引擎的标记一直在进行,但是清除,只有在内存满了,或者达到某个条件,GC垃圾回收机制才会介入。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • GC算法 CG就是垃圾回收机制的简写,顾名思义就是找到内存中的垃圾、并释放和回收空间。 所谓垃圾就是程序中不再需要...
    汤姆威廉斯阅读 539评论 0 0
  • 在不断学习的过程中将学习到的知识整理成一个个知识模块,尽量保持其完整性与形成知识网络是编写这些文字的初衷。PS这是...
    littleSatr阅读 482评论 0 1
  • 关于V8 V8是一款主流的js执行引擎。它是为JS在浏览器执行而打造的。因此不会遇到大量使用内存的场景。所以它申请...
    小q阅读 520评论 0 0
  • V8的垃圾回收机制与内存限制 V8的内存限制 在一般的后端开发语言中,在基本的内存使用上没有什么限制,然而在Nod...
    Upcccz阅读 1,494评论 1 3
  • V8主要的垃圾回收算法 V8的垃圾回收策略主要基于分代式垃圾回收机制,主要将内存分为新生代和老生代,V8堆的整体内...
    荔桑阅读 368评论 0 0