美文网首页
敲开内存管理以及垃圾回收的大门

敲开内存管理以及垃圾回收的大门

作者: 贰玖是只猫 | 来源:发表于2021-03-26 22:44 被阅读0次

作为一个前端同学我们跨过了只关注实现业务功能的阶段后,会进入一个瓶颈。在这个瓶颈阶段,我们需要通过更多的知识实践来积累,让我们跨过这段平台期。前端架构、框架原理、性能优化等都是我们需要取掌握的技能。本章节就从性能优化的一个角度----JavaScript性能优化 进化吧!

内存管理

如果我们在日常的编程中不注意管理内存,会导致内存泄露, 产生浏览器崩溃等情况。

内存管理: 开发者主动申请、使用、释放内存空间

//申请
let obj = {}
//使用
obj.name = "zicoo"
//释放
obj = null

JavaScript 中的垃圾回收

  • JavaScript中内存管理是自动的
  • 对象不再被引用时是垃圾
  • 对象不能从根上访问到时是垃圾

可达对象

  • 可以访问到的对象就是可达对象(引用、作用域链)
  • 可达的标准是从根触发是否能够被找到
  • javascirpt 中的根可以理解为全局变量对象

引用与可达

let obj = {name: "sam"}
let obj1 = obj
obj = null //obj 仍然可达

GC - 垃圾回收机制

  • GC是一种机制,垃圾回收器完成具体的工作
  • 工作的内容是查找垃圾释放空间、回收空间
  • 算法就是工作中查找和回收所遵循的规则

常见GC算法

  • 引用计数
  • 标记清除
  • 标记整理
  • 分代回收

引用计数

核心思想: 设置引用计数器,判断当前引用数为否为0

优点:

  • 发现垃圾立即回收
  • 最大限度减少程序暂停

缺点:

  • 无法回收循环引用的对象
  • 时间开销大
function fn() {
    const obj1 = {}
    const obj2 = {}

    obj1.name = obj2
    obj2.name = obj1 //obj1 obj2 循环引用 无法将引用计数器清0
}
fn()

标记清除

核心思想: 分标记和清除两个阶段

  • 遍历所有对象找到标记活动对象
  • 遍历所有对象清除没有标记的对象
  • 回收相应的空间

执行时间点: 当有效内存空间被耗尽的时候,会停止程序执行标记清除

标记活动对象依旧是从根出发,递归的方式遍历从根能到达的所有节点,并且标记为活动对象, 而未标记活动对象的节点则就是待回收节点

优点:

  • 对于循环引用的对象可以被回收,可以弥补引用计数的缺点

缺点:

  • 由于内存空间申请的时候是有序申请,但是回收的时候节省的内存空间信息是不会整合的,导致节省的内存空间不连续,从而造成空间碎片化

标记整理

  • 标记整理算法是标记清除的增强
  • 标记阶段的操作和标记清除一致
  • 清除阶段会先执行整理,移动对象位置, 使时间碎片连续

V8引擎

  • 主流的JavaScript执行引擎
  • V8采用即时编译
  • V8内存设限 (64位系统不超过 1.5G 21位系统不超过800M)

V8垃圾回收策略

  • 采用分代回收的思想
  • 内存分为新生代、老声带
  • 针对不同的对象采用不同算法

V8常见GC算法

  • 分代回收
  • 空间复制
  • 标记清除
  • 标记整理
  • 标记增量

V8 新生代对象回收

  • V8 内存空间一分为二
  • 小空间用于存储新生代对象(64位32M | 32位16M)
  • 新生代对象指存活时间较短的对象
    例如:局部作用域的变量是新生代, 全局变量存是老年代

新生代对象回收实现

  • 回收过程采用复制算法 + 标记整理
  • 新生代内存区分为两个等大空间
  • 使用空间为From 状态, 空闲空间为 To状态
  • 活动对象存于From 空间
  • 等到回收阶段,标记整理后会将活动对象拷贝到To
  • 释放掉From
    细节说明
  • 拷贝过程中可能出现晋升
  • 晋升就是将新生代对象移动至老年代
  • 一轮GC还存活的新生代需要晋升
  • To 空间使用率超过25%,之后拷贝的对象则会晋升

V8 老年代对象回收

  • 老年代64位操作系统1.4G ,32位操作系统700m
  • 老年代活动对象指存活时间较长的对象

老年代对象回收实现

  • 主要采用标记清除、标记整理、增量标记算法
  • 首先使用标记清除完成垃圾空间的回收(存在空间碎片)
  • 采用标记整理进行空间优化(新生代晋升时,老年代区域不足以存放新生代对象)
  • 采用增量标记进行效率优化

增量标记
程序执行与标记间隔执行,达到清理标准一起清理

细节对比

  • 新生代区域垃圾回收使用空间换时间
  • 老年代区域垃圾回收空间大,不适合复制算法

相关文章

  • 敲开内存管理以及垃圾回收的大门

    作为一个前端同学我们跨过了只关注实现业务功能的阶段后,会进入一个瓶颈。在这个瓶颈阶段,我们需要通过更多的知识实践来...

  • Java GC

    概述 GC => 垃圾回收 = 回收可用空间 + 压缩内存 内存管理 手动内存管理 => C | C++ 自动内存...

  • Javascript垃圾回收机制

    简介 JS自带一套内存管理引擎,负责创建对象、销毁对象,以及垃圾回收。这期探讨一下垃圾回收机制。垃圾回收机制主要是...

  • android--垃圾回收与内存优化

    什么是垃圾回收 对比C/C++这种需要自己管理内存的语言 java可以实现自动内存管理和回收 垃圾回收器负责回收程...

  • JavaScript 语言性能优化

    说明: 具体从内存空间的使用以及垃圾回收机制的角度出发。 内存管理 为什么要进行内存管理内存.png内存管理是可以...

  • 安卓技能点

    技术方面: 掌握Java开发,以及对JVM以及Java内存管理,java内存区域与溢出、垃圾回收有较深入的理解; ...

  • 常见GC算法与V8引擎

    内存管理 垃圾回收与常见GC算法 V8引擎的垃圾回收 Performance工具 代码优化实例 内存管理 为什么要...

  • Java 内存泄漏

    前言: Java语言的一个关键的优势就是它的内存管理机制。你只管创建对象,Java的垃圾回收器帮你分配以及回收内存...

  • JAVA进阶(6)—— 内存泄露

    Java语言的一个关键的优势就是它的内存管理机制。你只管创建对象,Java的垃圾回收器帮你分配以及回收内存。然而,...

  • Android性能调优(4) — 内存泄漏与内存抖动

    在上一遍《Android性能调优(3)—内存管理与垃圾回收》我们对Android内存管理与垃圾回收有了一定的认识。...

网友评论

      本文标题:敲开内存管理以及垃圾回收的大门

      本文链接:https://www.haomeiwen.com/subject/iofdhltx.html