Table of contents
Open Table of contents
211. V8 垃圾回收机制
V8 的垃圾回收机制 (Garbage Collection, GC) 主要通过分代垃圾回收 (Generational Garbage Collection) 技术来管理内存。这种机制将堆内存分为新生代和老生代,并对不同代的对象使用不同的回收策略,以优化内存管理和回收性能。
分代垃圾回收
-
新生代 (New Space):
- 新生代是用于存放生命周期较短的对象的区域。
- 新生代又分为两个空间:From Space 和 To Space。
- 新生代对象在两个空间之间进行复制和交换。
-
老生代 (Old Space):
- 老生代是用于存放生命周期较长的对象的区域。
- 当对象在新生代经过多次回收后仍然存活,它们将被晋升到老生代。
垃圾回收算法
新生代垃圾回收 (Scavenge)
- Scavenge 算法:
- 新生代垃圾回收使用 Scavenge 算法,具体实现为 Cheney 算法。
- 新分配的对象首先放入 From Space。
- 当 From Space 填满时,执行垃圾回收,将存活的对象复制到 To Space,并清空 From Space。
- 最后,交换 From Space 和 To Space 的角色。
老生代垃圾回收 (Mark-Sweep, Mark-Compact)
- Mark-Sweep 和 Mark-Compact:
- 老生代垃圾回收使用标记-清除 (Mark-Sweep) 和标记-整理 (Mark-Compact) 算法。
- 标记阶段 (Mark):
- 遍历堆中的对象,标记活跃对象。
- 清除阶段 (Sweep):
- 回收未标记的对象,释放内存空间。
- 整理阶段 (Compact):
- 将存活的对象移动到内存的一端,减少内存碎片,提高分配效率。
并发和增量垃圾回收
-
并发标记 (Concurrent Marking):
- V8 在进行标记-清除和标记-整理时,会尽量并发进行标记工作,以减少暂停时间。
- 在标记阶段,JavaScript 执行线程和标记线程并发运行。
-
增量垃圾回收 (Incremental GC):
- 增量垃圾回收将垃圾回收过程分解成多个小步骤,在应用程序执行过程中逐步完成,减少一次性暂停时间,提升应用的响应速度。
大对象空间和代码空间
-
大对象空间 (Large Object Space):
- 大对象直接分配在单独的大对象空间中,不参与新生代和老生代的分代回收。
- 这种设计减少了大对象移动和复制的成本。
-
代码空间 (Code Space):
- 存储 JIT 编译生成的机器码。
总结
V8 并没有使用引用计数作为主要的垃圾回收策略,引用计数是一种较为简单的垃圾回收策略,他跟踪对象的引用计数,当计数将为 0 时,对象被回收。然而,引用计数在处理循环引用等情况下存在问题,并且不够搞笑
V8 的垃圾回收机制通过分代垃圾回收技术、并发和增量垃圾回收策略,以及各种优化措施,有效管理内存,提高 JavaScript 应用的性能和响应速度。
212. localStorage
vssessionStorage
vsindexedDB
vscookie
localStorage
、sessionStorage
、indexedDB
和 cookie
是用于在浏览器中存储数据的四种主要技术。它们各有特点和适用场景。
localStorage
-
特点
-
持久性:数据存储在浏览器中,持久保存,直到用户手动清除浏览器缓存或通过代码删除。
-
存储大小:通常每个域名下可以存储约 5-10MB 的数据。
-
数据类型:只能存储字符串数据,如果需要存储对象或数组,需要将其序列化为 JSON 字符串。
-
同步访问:
localStorage
的所有操作都是同步的,可能会阻塞主线程。
-
-
适用场景
- 存储用户偏好设置、主题选择等长期保留的数据。
- 保存不敏感的用户信息,如用户名、设置等。
sessionStorage
-
特点
-
持久性:数据仅在当前会话(浏览器窗口或标签页)中有效,当会话结束(窗口或标签页关闭)时,数据会被清除。
-
存储大小:通常每个域名下可以存储约 5-10MB 的数据。
-
数据类型:同样只能存储字符串数据,需要序列化非字符串数据。
-
同步访问:
sessionStorage
的所有操作也是同步的。
-
-
适用场景
- 存储仅在会话期间有效的数据,如临时表单数据、认证令牌等。
- 需要在同一个会话中共享数据,但不希望数据在会话结束后仍然存在。
indexedDB
-
特点
-
持久性:数据持久存储,直到用户手动清除浏览器缓存或通过代码删除。
-
存储大小:可以存储大量数据,通常限制为数百 MB 甚至更多,具体取决于浏览器。
-
数据类型:可以存储复杂的数据结构,如对象、数组、二进制数据等。
-
异步访问:所有操作都是异步的,通过事件或 Promise 处理,避免阻塞主线程。
-
数据库特性:提供事务、索引、键值对存储等功能,类似于关系型数据库。
-
-
适用场景
- 需要存储大量数据或复杂数据结构的场景,如离线应用、文件存储等。
- 数据量大到超出
localStorage
或sessionStorage
的限制。
cookie
-
特点
-
持久性:可以通过设置
Expires
或Max-Age
属性来控制cookie
的有效期。 -
存储大小:每个
cookie
通常不能超过 4KB。 -
数据类型:只能存储字符串数据。
-
请求头传输:
cookie
会在每次 HTTP 请求时被自动发送到服务器。 -
跨子域共享:可以通过设置
domain
属性来跨子域名共享cookie
。
-
-
适用场景
- 需要在服务器和客户端之间共享的小数据,如认证信息、用户会话数据等。
- 跨子域名共享数据。
总结
特性 | localStorage | sessionStorage | indexedDB | cookie |
---|---|---|---|---|
持久性 | 持久存储,直到手动清除 | 会话存储,关闭窗口或标签页后清除 | 持久存储,直到手动清除 | 由 Expires 或 Max-Age 属性控制 |
同源策略 | 遵循同源策略,无法跨域访问 | 遵循同源策略,无法跨域访问 | 遵循同源策略 | 可以通过设置 domain 和 path 跨子域访问 |
存储大小 | 约 5-10MB | 约 5-10MB | 数百 MB 甚至更多 | 每个 cookie 约 4KB,总数有限制 |
数据类型 | 只能存储字符串 | 只能存储字符串 | 复杂数据结构(对象、数组、二进制) | 只能存储字符串 |
访问方式 | 同步 | 同步 | 异步 | 同步 |
请求头传输 | 不会随请求发送 | 不会随请求发送 | 不会随请求发送 | 每次请求都会发送,影响性能 |
适用场景 | 用户偏好设置、主题选择等 | 会话数据、临时数据 | 大量数据、复杂数据结构、离线应用 | 需要在服务器和客户端之间共享的数据,如认证信息 |
在选择哪种技术来存储数据时,需要考虑数据的持久性、大小限制、同源策略以及是否需要在服务器和客户端之间共享数据。localStorage
和 sessionStorage
适合存储较大的客户端数据,而 cookie
适合存储需要在服务器之间共享的小数据。indexedDB
则适合存储复杂和大量的数据。