您当前的位置: 首页 > 

寒冰屋

暂无认证

  • 3浏览

    0关注

    2286博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

检测Web浏览器上的内存泄漏

寒冰屋 发布时间:2021-11-04 08:40:06 ,浏览量:3

目录

背景

拍摄堆快照

一个真实世界的例子——AsyncSubject

附加说明

兴趣点

  • 下载源 - 1.2 KB
背景

当您关闭浏览器选项卡时,所有内存都将被释放。内存泄漏在Web浏览器上很可能不是大问题。但是如果你有一个长时间运行的应用程序,它可能是一个问题。这是关于如何检测Web浏览器上的内存泄漏的说明。在本说明中,我将使用示例来展示如何在开发工具上使用内存功能。我注意到Chrome和Edge上的开发工具是最容易使用的。

拍摄堆快照

在Chrome或Edge开发工具中,我们可以采用三种内存配置文件。

在这篇笔记中,我将重点关注“堆快照”,它非常有效地精确定位导致内存泄漏的对象。测试HTML页面如下:






    

    
    button {
        height: 60px;
        border-radius: 5px;
        font-weight: 800;
        background-color: aquamarine;
    }
    

Memory test - first attempt
    

let MTestClassesArray = [];
    
class MTestClass {
    constructor() {}
}
    
const create_1000_objects = () => {
    for(let i = 0; i < 1000; i++) {
        MTestClassesArray.push(new MTestClass());
    }
    
    const text = `Total ${MTestClassesArray.length} `
        + `MTestClass objects created`;
    document.getElementById('divMsg').innerHTML = text;
};
    

    

    

    
        Create 1000 MTestClass objects
    
    

  • 在这个HTML页面中,我们有一个按钮。
  • 每次单击按钮,都会创建1000个“MTestClass”类型的对象。
  • 每个对象都插入到数组“ MTestClassesArray”中。
  • 由于数组“MTestClassesArray”是在全局范围内声明的,因此对象不再是可垃圾回收的。

为了验证上述陈述,让我们加载页面并单击几次按钮。在我的实验中,我使用了Edge。

正如页面中所示,我已单击该按钮3次,并创建了3000 个“MTestClass”对象。我们可以通过“CTRL+SHIFT+i”调出开发工具。在获取内存快照之前,让我们首先强制进行垃圾回收。

然后我们可以在垃圾收集之后拍摄内存快照。

内存快照使我们能够很好地了解内存堆。

  • 我们可以过滤快照以检查某些类类型的对象是否在内存堆中。在我们的示例中,我们可以看到正好3000个“ MTestClass”对象。
  • 我们还可以看到是什么对象阻止了“ MTestClass”对象被垃圾收集。在我们的示例中,它是“MTestClassesArray”对象。

开发工具甚至可以告诉我们哪一行代码创建了“MTestClass”对象。

一个真实世界的例子——AsyncSubject

如果您订阅了一个事件,则需要取消订阅它。如果没有,很可能是内存泄漏。但是rxjs中的 "AsyncSubject"是这样吗?






    

    
    button {
        height: 60px;
        border-radius: 5px;
        font-weight: 800;
        background-color: aquamarine;
    }
    

Memory test - async subject

    

const get_time = () => {
    const element = document.getElementById('divTime');
    const subject = new rxjs.AsyncSubject();
    
    element.innerHTML = '';
    
    setTimeout(() => {
        subject.next(new Date());
        subject.complete();
    
    }, 3 * 1000);
    
    subject.subscribe((data) => {
        element.innerHTML = data.toString();
    });
};    
    


    

    Get Time by AsyncSubject
    

  • 在这个HTML页面中,我们有一个按钮。
  • 点击按钮,页面上会显示当前时间。
  • 我没有直接获取时间,而是创建了一个“AsyncSubject”,时间是在定时器回调函数中获取的。
  • 然后程序订阅“AsyncSubject”并将其显示在页面上。

需要注意的是,“AsyncSubject”是在“get_time”箭头函数中创建的,因此与任何全局上下文无关。我将假设它在计时器回调之后是可垃圾回收的。但是让我们确认它正在使用开发工具。

单击按钮和显示时间之间有3秒的延迟。为了确认“AsyncSubject”是可垃圾回收的,让我们拍两个堆快照。一个在定时器回调之前,一个在定时器回调之后。

在定时器回调之前,我们可以在内存堆中找到“AsyncSubject”。此时,它不是垃圾回收的,因为它被一些其他资源保留并且最终可以从window对象访问。

但是在定时器回调之后,AsyncSubject收集了“ ”。如果没有收集,您可以手动强制收集。通过这个例子,我们可以对我们的程序更有信心。如果“ AsyncSubject”使用正确,我们不需要取消订阅该事件。

附加说明
  • 已经注意到,如果你曾经“console.log()”一个对象,它就不再是可垃圾回收的。在生产版本中,如果您有内存问题,您应该记住这一点。
  • 在堆快照中搜索对象时,如果您的程序被缩小,则可以通过缩小器更改类的名称。
兴趣点
  • 这是关于如何检测Web浏览器上的内存泄漏的说明。
  • 开发工具对于我们了解内存堆非常有用。
  • 我希望你喜欢我的文章,我希望这篇笔记能以一种或另一种方式帮助你。

Detect Memory Leak on Web Browsers - CodeProject

关注
打赏
1665926880
查看更多评论
立即登录/注册

微信扫码登录

0.0563s