1. 内存泄漏

1.1 什么是内存泄漏?

程序的运行需要内存。只要程序提出要求,操作系统或者运行时(runtime)就必须供给内存。

对于持续运行的服务进程(daemon),必须及时释放不再用到的内存。否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃。

不再用到的内存,没有及时释放,就叫做内存泄漏(memory leak)。

这很麻烦,所以大多数语言提供自动内存管理,减轻程序员的负担,这被称为"垃圾回收机制"(garbage collector)。

1.2 垃圾回收机制

垃圾回收机制怎么知道,哪些内存不再需要呢?

并不是说有了垃圾回收机制,程序员就轻松了。你还是需要关注内存占用:那些很占空间的值,一旦不再用到,你必须检查是否还存在对它们的引用。如果是的话,就必须手动解除引用。

1.3 内存泄漏的识别方法

怎样可以观察到内存泄漏呢?

如果连续五次垃圾回收之后,内存占用一次比一次大,就有内存泄漏。这就要求实时查看内存占用。

Chrome 浏览器查看内存占用,按照以下步骤操作。

  1. 打开开发者工具,选择 Timeline 面板
  2. 在顶部的Capture字段里面勾选 Memory
  3. 点击左上角的录制按钮。
  4. 在页面上进行各种操作,模拟用户的使用情况。
  5. 一段时间后,点击对话框的 stop 按钮,面板上就会显示这段时间的内存占用情况。

如果内存占用基本平稳,接近水平,就说明不存在内存泄漏。反之,就是内存泄漏了。

1.4 WeakMap

前面说过,及时清除引用非常重要。但是,你不可能记得那么多,有时候一疏忽就忘了,所以才有那么多内存泄漏。

最好能有一种方法,在新建引用的时候就声明,哪些引用必须手动清除,哪些引用可以忽略不计,当其他引用消失以后,垃圾回收机制就可以释放内存。这样就能大大减轻程序员的负担,你只要清除主要引用就可以了。

ES6 考虑到了这一点,推出了两种新的数据结构:WeakSet 和 WeakMap。它们对于值的引用都是不计入垃圾回收机制的,所以名字里面才会有一个"Weak",表示这是弱引用。

下面以 WeakMap 为例,看看它是怎么解决内存泄漏的。

  1. const wm = new WeakMap();
  2. const element = document.getElementById('example');
  3. wm.set(element, 'some information');
  4. wm.get(element) // "some information"

上面代码中,先新建一个 Weakmap 实例。然后,将一个 DOM 节点作为键名存入该实例,并将一些附加信息作为键值,一起存放在 WeakMap 里面。这时,WeakMap 里面对element的引用就是弱引用,不会被计入垃圾回收机制。

也就是说,DOM 节点对象的引用计数是1,而不是2。这时,一旦消除对该节点的引用,它占用的内存就会被垃圾回收机制释放。Weakmap 保存的这个键值对,也会自动消失。

基本上,如果你要往对象上添加数据,又不想干扰垃圾回收机制,就可以使用 WeakMap。

2. 多iframe引起的内存问题

多iframe引起的内存问题主要表现在IE浏览器上,存在的问题

会存在iframe窗口关闭了但是IFrame对象内存不释放。

el.src可能还没有执行完,就执行后面的语句,建议设置成‘about: blank’

如果IFrame中包含的是跨域内容,则会提示没有权限;

窗体关闭的比脚本执行的快,内存仍然没有释放;

最终的处理方式

  1. function removeFrame() {
  2. let el = document.getElementById("frame");
  3. // 取消窗口监听事件
  4. if (el) {
  5. el.src = "about:blank";
  6. if (el.contentWindow) {
  7. try {
  8. el.contentWindow.document.write('');
  9. el.contentWindow.document.clear();
  10. el.contentWindow.close()
  11. } catch(e){
  12. // todo
  13. }
  14. }
  15. const p = el.parentNode;
  16. if(p){
  17. p.removeChild(el);
  18. }
  19. try {
  20. window.CollectGarbage()
  21. } catch (e) {
  22. // todo
  23. }
  24. el = null
  25. }
  26. }

多iframe应用引起的内存问题的更多相关文章

  1. 解决IE浏览器IFrame对象内存不释放问题

    最近项目组发现在使用showModalDialog弹出窗体中如果包含IFrame对象,则IFrame对象占用的内存资源在窗体关闭后不会释放.弹出关闭反复多次后,IE浏览器内存占用可超过数百M,严重时I ...

  2. iframe动态创建及释放内存

    近期參与一个项目的开发,因为项目是基于浏览器的胖client(RIA)应用程序,页面中大量调用iframe.后期測试发现浏览器内存一直居高不下,并且打开iframe页面越多内存占用越大.在IE系列浏览 ...

  3. jquery load 和 iframe 比较

    如果要加载的东西比较简单,里面的没有复杂的数据和逻辑,可以使用load.如果要加载的页面自身有复杂的逻辑.操作,还是建议使用ifame,因为iframe里面可以引入自身的js和样式,而load引入的东 ...

  4. 新手入门:史上最全Web端即时通讯技术原理详解

    前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为 ...

  5. Web端即时通讯技术原理详解

    前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为 ...

  6. 基于web的IM软件通信原理分析

    关于IM(InstantMessaging)即时通信类软件(如微信,QQ),大多数都是桌面应用程序或者native应用较为流行,而网上关于原生IM或桌面IM软件类的通信原理介绍也较多,此处不再赘述.而 ...

  7. web端及时通讯原理

    前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为 ...

  8. window.print()局部打印三种方式

    首先准备要打印的内容,也可以打印时再填充,html中定义如下: <!--startprint--> <div id="printcontent" style=&q ...

  9. 新手入门贴:史上最全Web端即时通讯技术原理详解

    关于IM(InstantMessaging)即时通信类软件(如微信,QQ),大多数都是桌面应用程序或者native应用较为流行,而网上关于原生IM或桌面IM软件类的通信原理介绍也较多,此处不再赘述.而 ...

随机推荐

  1. python练习:编写一个程序,要求用户输入一个整数,然后输出两个整数root和pwr,满足0<pwr<6,并且root**pwr等于用户输入的整数。如果不存在这样一对整数,则输入一条消息进行说明。

    python练习:编写一个程序,要求用户输入一个整数,然后输出两个整数root和pwr,满足0<pwr<6,并且root**pwr等于用户输入的整数.如果不存在这样一对整数,则输入一条消息 ...

  2. enviroment linux jdk and git and maven

    #java_home export JAVA_HOME=/usr/local/java/jdk1.8.0_211 export JRE_HOME=$JAVA_HOME/jre export CLASS ...

  3. Windows 查看并关闭占用指定端口的程序

    windows关闭端口的小工具: 链接:https://pan.baidu.com/s/1ZGL4cdSluy0lbi3tDERUvA 提取码:spxy 查看指定端口的使用情况 netstat -an ...

  4. 25 JavaScript对象原型&ES5新的对象方法

    JavaScript对象原型 所有JavaScript对象都从原型继承对象和方法 日期对象继承自Date.prototype,数组继承自Array.prototype,对象构造器新建的对象Person ...

  5. WLC RTU license

    目前思科的某些WLC不是一定要license文件去安装,例如这里提到的RTU license. RTU:Right To Use Right to Use (RTU) licensing is a m ...

  6. java 关于多层的异常捕获

    从这两个源程序可以看出来,这里的逻辑其实很好理清楚. 可以看到,每次抛出了相同的错误,但因为catch后的捕捉类型不同,所以结果不同,其实可以看出多层的异常捕捉和正常的多层代码运行逻辑是基本一致的.

  7. kafka创建topic报错

    kafka执行如下创建topic的语句: [root@node01 kafka_2.11-1.0.0]# bin/kafka-topics.sh --create --topic streaming- ...

  8. Android开发Intent应用概述

    原文: http://bbs.gfan.com/android-93448-1-1.html 今天,我们来研究一下Intent,没错,就是前面说过的比较难理解的那个东西,希望通过这篇文章之后,你发现前 ...

  9. EBCDIK,EBCDIC,ASCII,shift JIS間の変換

    http://itdoc.hitachi.co.jp/manuals/3020/3020759580/G5950334.HTM#ID01056

  10. 大数据篇:YARN

    YARN YARN是什么? YARN是一种新的 Hadoop 资源管理器,它是一个通用资源管理系统,可为上层应用提供统一的资源管理和调度,它的引入为集群在利用率.资源统一管理和数据共享等方面带来了巨大 ...