浏览器中的内存泄露(续)

4.内存泄露的解决方案

  • 显式类型转换

首先说说最容易处理的情况 对于类型转换造成的错误,我们可以通过显式类型转换来避免:

var s=newString("lalalalala");//此处将string转换成object
alert(s.length);

 这个太容易了,算不上正经方案。不过类型转换泄露也就这一种处理方法了。

  • 避免事件导致的循环引用

在比较成熟的js程序员里,把事件函数写成闭包是再正常不过了:

function A(){
    
var a=document.createElement("div");
    a.onclick
=function(){
        alert(
"hi");
    }
}

这将导致内存泄露。按照IBM那两位老大的说法,当然是把函数放外面或者a=null就没问题了,不过还要访问A()里面的变量呢?假如有下面的代码:

 

function A(){
    
var a=document.createElement("div");
    
var b=document.createElement("div");
    a.onclick
=function(){
        alert(b.outerHTML);
    }
    
return a;
}

 如何将它的逻辑表达出来 还避免内存泄露? 分析一下这个内存泄露的形式:只要onclick的外部环境中不包含a那么,就不会泄露。那么办法有2个一是将环境到a的引用断开 另一个是将function到环境的引用断开,但是,如果要在函数中访问b就不能将Function放到外面,如果要返回a的值,就不能a=null,怎么办呢?

解决方案1:

构造一个不含a的新环境

function A(){
    
var a=document.createElement("div");
    
var b=document.createElement("div");
    a.onclick
=BuildEvent(b);
    
return a;
}

function BuildEvent(b)
{
    
return function(){
        alert(b.outerHTML);
    }
}

a本身可以通过this访问,将其它需要访问的外层函数变量传递给BuildEvent就可以了。保持BuildEvent定义和调用的参数名一致,会带来方便。

 

解决方案2:

在return 之后a=null,不可能? 看看下面:

function A(){
    
try{
        
var a=document.createElement("div");
        
var b=document.createElement("div");
        a.onclick
= function(){
            alert(b.outerHTML);
        }
        
return a;
    } 
finally {
        a
=null;
    }
}

finally在try之后执行,如果finall块不返回值,才会返回try块的返回值。

  • 延迟appendChild

还记得函数的lazy initalize吧,对于ie恶心至极的DOM操作泄露,我们需要用类似的方法去处理。在一个函数中构造一个复杂对象,在需要的时候将之appendChild到DOM树上,这是很常见的做法,但在IE6中,这样做将导致所谓的"插入顺序内存泄露",没有别的办法,我们只能用一个数组parts保存子节点,编写一个appendTo方法先序遍历节点树,去把它挂在某个DOM节点上。

function appendTo(Element)
{
    Element.appendChild(
this);
    
if(!this.parts)return;
    
for(var i=0;i<this.parts.length;i++)
        parts.appendTo(
this);
}
  • 垃圾箱

对于ie7,我比较无可奈何,因为DOM对象不会被CG程序回收,只有离开页面时会被回收,所以我的建议是:使用DOM要有节制,尽量多用innerHTML吧...... good luck.

一旦你使用了DOM对象,千万不要试图o=null,你可以设置一个叫做Garbage的div并且将其display设置为none,将不用的DOM对象存入其中(就是appendChild上去)就好了

  • 代理对象

这是Ext的做法,这里只是顺带提一下。将每个元素用一个"代理对象"操作,不论appendChild还是其他操作都不是对DOM对象本身的操作,而是通过这个代理对象操作。这是一个很不错的Proxy模式,不过要想避免泄露还是需要一点功夫的,并非用了Proxy之后就不会泄露,有时反而更容易泄露。

5 .FAQ

  1. 内存泄露是内存占用很大么? 不是,即使1byte内存也叫做内存泄露。
  2. 程序中提示,内存不足,是内存泄露么?不是,这一般是无限递归函数调用导致栈内存溢出。
  3. 内存泄露是哪个区域泄露?堆区,栈区是不会泄露的。
  4. window对象是DOM对象么?不是,window对象参与的循环引用不会内存泄露。
  5. 内存泄露后果是什么?大多数时候后果不很严重,但过多DOM操作会导致网页执行变慢。
  6. 跳转页面后,内存泄露仍然存在么?仍然存在,直到关闭浏览器。
  7. FireFox也会内存泄露么?FF2仍然有内存泄露
下载方式:https://pan.quark.cn/s/c9b9b647468b ### 初级JSP程序设计教程核心内容解析#### 一、JSP基础概述JSP(JavaServer Pages)是由Sun Microsystems公司创建的一种动态网页技术规范,主要应用于构建动态网站及Web应用。JSP技术使得开发者能够将动态数据与静态HTML文档整合,从而实现网页内容的灵活性和可变性。##### JSP的显著特性:1. **动态与静态内容的分离**:JSP技术支持将动态数据(例如数据库查询结果、实时时间等)嵌入到静态HTML文档中。这种设计方法增强了网页的适应性和可维护性。2. **易用性**:开发者可以利用常规的HTML编辑工具来编写静态部分,并通过简化的标签技术将动态内容集成到页面中。3. **跨平台兼容性**:基于Java平台的JSP具有优良的跨操作系统运行能力,能够在多种不同的系统环境中稳定工作。4. **强大的后台支持**:JSP能够通过JavaBean组件访问后端数据库及其他资源,以实现复杂的数据处理逻辑。5. **执行效率高**:JSP页面在初次被请求时会被转换为Servlet,随后的请求可以直接执行编译后的Servlet代码,从而提升了服务响应的效率。#### 二、JSP指令的运用JSP指令用于设定整个JSP页面的行为规范。这些指令通常放置在页面的顶部,向JSP容器提供处理页面的相关指导信息。##### 主要的指令类型:1. **Page指令**: - **语法结构**:`<%@ page attribute="value" %>` - **功能**:定义整个JSP页面的运行特性,如设定页面编码格式、错误处理机制等。 - **实例**: ...
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值