Skip to content

Latest commit

 

History

History
90 lines (90 loc) · 4.83 KB

内存专题.md

File metadata and controls

90 lines (90 loc) · 4.83 KB

###内存专题

  • JAVASCRIPT的内存回收机制
    • 以Google的V8引擎为例,在V8引擎中所有的JAVASCRIPT对象都是通过来进行内存分配的。当我们在代码中声明变量赋值时,V8引擎就会在堆内存中分配一部分给这个变量。如果已申请的内存不足以存储这个变量时,V8引擎就会继续申请内存,直到的大小达到了V8引擎的内存上限为止(默认情况下,V8引擎的堆内存的大小上限在64位系统中为1464MB,在32位系统中则为732MB)。
    • 另外,V8引擎对堆内存中的JAVASCRIPT对象进行分代管理
      • 新生代。
        • 新生代即存活周期较短的JAVASCRIPT对象,如临时变量、字符串等
      • 老生代。
        • 老生代则为经过多次垃圾回收仍然存活,存活周期较长的对象,如主控制器、服务器对象等。
  • 垃圾回收算法。
    • 垃圾回收算法一直是编程语言的研发中是否重要的​​一环,而V8引擎所使用的垃圾回收算法主要有以下几种。
      • Scavange算法:通过复制的方式进行内存空间管理,主要用于新生代的内存空间;
      • Mark-Sweep算法和Mark-Compact算法:通过标记来对堆内存进行整理和回收,主要用于老生代对象的检查和回收。
  • 对象进行回收。
    • 引用
      • 当函数执行完毕时,在函数内部所声明的对象不一定就会被销毁。
      • 引用(Reference)是JAVASCRIPT编程中十分重要的一个机制。
        • 是指代码对对象的访问这一抽象关系,它与C/C++的指针有点相似,但并非同物。引用同时也是JAVASCRIPT引擎在进行垃圾回收中最关键的一个机制。
				var val = 'hello world';
				function foo() {
				  return function() {
				    return val;
				  };
				}
				global.bar = foo();
		- 当代码执行完毕时,对象`val`和`bar()`并没有被回收释放,`JAVASCRIPT`代码中,每个`变量`作为单独一行而不做任何操作,`JAVASCRIPT`引擎都会认为这是对`对象`的访问行为,存在了对`对象的引用`。为了保证`垃圾回收`的行为不影响程序逻辑的运行,`JAVASCRIPT`引擎不会把正在使用的`对象`进行回收。所以判断`对象`是否正在使用中的标准,就是是否仍然存在对该`对象`的`引用`。
		- `JAVASCRIPT`的`引用`是可以进行`转移`的,那么就有可能出现某些引用被带到了全局作用域,但事实上在业务逻辑里已经不需要对其进行访问了,这个时候就应该被回收,但是`JAVASCRIPT`引擎仍会认为程序仍然需要它。
  • IE下闭包引起跨页面内存泄露。
  • JAVASCRIPT的内存泄露处理
    • DOM对象添加的属性是一个对象的引用。
		var MyObject = {};
		document.getElementByIdx_x('myDiv').myProp = MyObject;
	解决方法:在window.onunload事件中写上: 
		document.getElementByIdx_x('myDiv').myProp = null;
- DOM对象与JS对象相互引用。
		function Encapsulator(element) {
		   this.elementReference = element;
		   element.myProp = this;
		}
		new Encapsulator(document.getElementByIdx_x('myDiv'));
	解决方法:在onunload事件中写上: 
		document.getElementByIdx_x('myDiv').myProp = null;
- 给DOM对象用attachEvent绑定事件。
		function doClick() {}
		element.attachEvent("onclick", doClick);
	解决方法:在onunload事件中写上: 
		element.detachEvent('onclick', doClick);
- 从外到内执行appendChild。这时即使调用removeChild也无法释放。
		var parentDiv =   document.createElement_x("div");
		var childDiv = document.createElement_x("div");
		document.body.appendChild(parentDiv);
		parentDiv.appendChild(childDiv);
	解决方法:从内到外执行appendChild:
		var parentDiv =   document.createElement_x("div");
		var childDiv = document.createElement_x("div");
		parentDiv.appendChild(childDiv);
		document.body.appendChild(parentDiv);
- 反复重写同一个属性会造成内存大量占用(但关闭IE后内存会被释放)。
		for(i = 0; i < 5000; i++) {
		   hostElement.text = "asdfasdfasdf";
		}
	这种方式相当于定义了5000个属性,解决方法:无。
  • 内存不是缓存
    • 不要轻易将内存当作缓存使用。
    • 如果是很重要的资源,请不要直接放在内存中,或者制定过期机制,自动销毁过期缓存
  • CollectGarbage
    • CollectGarbageIE的一个特有属性,用于释放内存的使用方法,将该变量或引用对象设置为nulldelete然后在进行释放动作,在做CollectGarbage前,要必需清楚的两个必备条件:(引用)。
      • 一个对象在其生存的上下文环境之外,即会失效。
      • 一个全局的对象在没有被执用(引用)的情况下,即会失效