测试文章3

10/24/2024
// 内容数据
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 标记清除

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

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

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

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

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

闭包造成的内存泄漏

闭包循环引用

案例1 image.png

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

案例2

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

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

image.png

重复注册事件

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

意外的全局变量

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

V8对GC的优化

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

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

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

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

新生代回收机制

Scavenge 的算法进行垃圾回收

老生代回收机制

整体流程: 标记清楚法

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

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