测试文章3

October 24, 2024
1 min read
Article
js
// 内容数据 const content = ref(''); async function fetchContent() { const response = await api.get(`/api/articles/detail/${blogName}`); content.value = response.content; }

1.like 2.unlike

内存中的堆和栈#

栈: 用于存储静态数据(原始值)

引擎会为这些值分配固定数量的内存

堆: 动态内存分配(按需分配)

JavaScript当中的引用#

JS中的变量都是指向栈的 ==如果变量的值是一个非原始值, 那么栈中会有一个指向堆中对象的引用== 如何处理垃圾收集器内容 识别到了给定的变量不再被需要了, 就会释放他占用的内存

如何收集多余的内存#

有哪些方式? 1.引用计数 2.标记清除

引用计数 收集那些没有指向它们引用的对象 缺点 没有考虑到循环引用的情况

image.png

image.png

标记清除

==检测能否从根对象上访问==

将永远无法到达的对象当做垃圾收集

JavaScript 代码中无法通过任何方式(例如变量、函数调用等)访问到的对象

可能会造成内存泄漏的原因

  • 定时器
  • 全局变量
  • 回调函数
  • 丢失的DOM引用

闭包造成的内存泄漏#

闭包循环引用

案例1

image.png

image.png

所以存在…⟶foo⟶inner⟶bar⟶foo(赋值给bar的foo,即上一次的foo)…

案例2

需要注意到这个地方如果说到循环引用的话, 可能需要声明一下是针对比较老的浏览器版本....

由于IE9之前的版本对JScript对象和COM对象使用不同的垃圾收集例程,因此闭包在IE的这些版本中会导致一些特殊的问题。具体来说,如果闭包的作用域中保存着一个HTML元素,那么就意味着该元素将无法被销毁。

image.png

image.png

重复注册事件

  1. 仅在页面创建的时候注册一次事件
  2. 页面离开的时候移除所有的事件

意外的全局变量

js
function fn() { foo = createBigData(); // 意外的全局变量导致内存泄漏 }

V8对GC的优化#

针对于大, 老, 存活时间长和小, 新, 存活时间长的对象来说, 使用同样的检测频率并不是非常合理

==采用一小块内存频率较高的快速清理,而一些大、老、存活时间长的对象作为老生代,使其很少接受检查,新老生代的回收机制及频率是不同的==

下题:

image.png

image.png

根据上面的说法, C和D都有可能会导致标记清除当中会被清除, 但是是否在新生代还是老生代, 什么时候检测, 执行标记清楚? 时机上并不怎么清楚

堆的大小 = 新生代大小 + 老生代大小

新生代回收机制#

Scavenge 的算法进行垃圾回收

老生代回收机制#

整体流程: 标记清楚法

从根元素出发, 递归遍历这个根元素:

  1. 能够到达的元素--活动对象
  2. 不能够到达的元素--非活动对象

Thanks for reading!