介绍
  低层次的语言,如C,具有低级别的内存管理命令,如:malloc()和free(),需要开发者手工释放内存。然而像javascript这样的高级语言情况则不同,对象(objects, strings 等)创建的时候分配内存,当他们不在使用的时候内存会被自动回收,这个自动回收的过程被称为垃圾回收。因为垃圾回收的存在,让javascript等高级语言开发者产生了一个错误的认识,以为可以不用关心内存管理。
  内存生命周期
  不管什么样的编程语言,内存的生命周期基本上是一致的。
1.分配你需要的内存
2.使用他进行读写操作
3.当内存不需要的时候,释放资源
  步骤1和步骤2对于所有语言都一样,能明显觉察到。至于步骤3,低级别语言需要开发者显式执行。而对于像javascript这样的高级语言,这部分操作是交给解析器完成的,所以你不会觉察到。
  javascript中的分配操作
  值的初始化
  在为变量赋值的时候,javascript会完成内存的分配工作。

var n = 123; // 为数字分配内存
var s = "azerty"; // 为字符串分配内存
var o = {
a: 1,
b: null
}; // 为包含属性值的object对象分配内存
var a = [1, null, "abra"]; // 为包含值的数组分配内存
function f(a){
return a   2;
} // 为函数分配内存(函数是可调用的对象)
// 函数表达式同样也是对象,存在分配内存的情况
someElement.addEventListener('click', function(){
someElement.style.backgroundColor = 'blue';
}, false);

通过函数调用完成分配
  一些函数当执行完毕之后,同样存在对象分配的情况发生。
var d = new Date();
var e = document.createElement('div'); // 分配一个 DOM 元素

一些方法会分配新值或者对象。
var s = "azerty";
var s2 = s.substr(0, 3); // s2 是一个新的字符串
// 由于字符串是不变的,javascript会为[0, 3]范围的内容创建一个新的字符串
var a = ["ouais ouais", "nan nan"];
var a2 = ["generation", "nan nan"];
var a3 = a.concat(a2); // 把 a 和 a2 结合在一起,产生一个新的数组

对值的使用
  对值的使用,其实也就是对分配后的内存执行读写操作。这些操作包括:对变量或者对象的属性进行读写操作,或者向函数传递参数。
  当不再需要的时候,释放内存
  绝大多数内存管理的问题都发生在这个阶段。最难做的事情是,如何判定分配的内存不再需要。这往往需要开发者做出判定,程序在什么时候不再需要内存,并释放他所占资源。
  高级语言的解析器中嵌入了一个叫做“垃圾收集器”的程序,他的工作是用来跟踪内存的分配和使用,判定内存是否被需要,在不再需要的时候执行资源释放操作。他只能获得一个近似值,因为判断一个内存是否被需要,这是个不确定的问题(不能通过一种算法解决)。
  垃圾回收
  正如上文所述,我们无法准确的做到自动判定“内存不再需要”。所以,垃圾回收对该问题的解决方案有局限性。本节将解释必要的概念,了解主要的垃圾收集算法和它们的局限性。
  引用
  垃圾回收中一个主要的概念是引用。在内存管理中,当一个对象无论是显式的还是隐式的使用了另外一个对象,我们就说他引用了另外一个对象。例如,javascript对象存在一个隐式的指向原型的引用,还有显式指向他的属性值的引用。
  在这里,对象的概念超出了javascript传统意义上对象的概念,他还包括函数作用域和全局作用域。
  使用引用计数算法的垃圾回收
  下面要介绍的是一种最理想化的算法,引入了 “对象不再需要” 和 “没有其他对象引用该对象” 的概念。当该对象的引用指针变为0的时候,就认为他可以被回收。
例子:
var o = { 
a: {
b:2
}
}; // 创建了两个对象. 一个对象(a)被另外一个对象(o引用的对象)引用,并把a作为他的属性
// 该对象又被变量o引用
// 很明显,这时没有对象能被回收
var o2 = o; // 变量 o2 再次引用了该对象
o = 1; // o 不再引用该对象,只有o2还在引用该对象
var oa = o2.a; // oa引用 o2 的属性对象 a
// 该对象被其他两个对象引用,分别是o2的属性a和oa变量
o2 = "yo"; // 该对象已经不再被其他对象引用了,但是他的属性a任然被oa变量引用,所以他还不能被释放
oa = null; // 现在属性a也不再被别的对象引用,该对象可以被回收了

限制:循环
  该算法有其局限性,当一个对象引用另外一个对象,当形成循环引用时,即时他们不再被需要了,垃圾收集器也不会回收他们。
function f(){
var o = {};
var o2 = {};
o.a = o2; // o 引用 o2
o2.a = o; // o2 引用 o
return "azerty";
}
f();
// 两个对象被创建,并形成相互引用
// 函数调用结束之后,他们不会脱离函数作用域,虽然他们不会被使用,但不会被释放
// 这是因为,引用计数的算法判定只要对象存在被引用的情况,那么就不能对其执行垃圾回收

现实中的例子
  ie6、7中,在dom对象上使用引用计数的算法,这里会存在内存泄露的问题。
var div = document.createElement("div");
div.onclick = function(){
doSomething();
}; // div 通过 click 属性引用了事件处理程序
// 当事件处理函数中访问了div变量的时候,会形成循环引用,将导致两个对象都不会被回收,造成内存泄露

标记 - 清除算法
  他引入了“对象不再需要”和“对象不可访问(对象不可达)”的概念。该算法假设有一系列的根对象(javascript中的根对象就是全局对象),每隔一段时间,垃圾收集器就会从根对象开始,遍历所以他引用的对象,然后再遍历引用对象引用的对象,以此类推。使用这种方式,垃圾收集器可以获得所有可访问的对象,回收那些不可访问的对象。
  这种算法比之前的算法好些,0引用的对象会被设置为不可访问对象,同时他也避免了循环引用造成的困恼。
  截止2012年,大多数现代浏览器使用的是这种“标记-清除算法”的垃圾回收器。JavaScript垃圾收集领域(代/增量/并发/并行的垃圾收集),在过去的几年改善了与之相关的算法,但是垃圾收集算法本身(标记-清除算法)和“如何判定一个对象不再需要”并没有得以改善。
  周期不再是一个问题
  在第一个例子中,函数调用结束之后,这两个对象不会被全局对象引用,也不会被全局对象引用的对象引用。因此,他们会被javascript垃圾回收器标记为不可访问对象。这种事情同样也发生在第二个例子中,当div和事件处理函数被垃圾回收器标记为不可访问,他们就会被释放掉。
  限制:对象需要明确的标记为不可访问
  这种标记的方法存在局限,但是我们在编程中被没有接触到他,所以我们很少关心垃圾回收相关的内容。

javascript的内存管理详解的更多相关文章

  1. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  2. HTML5数字输入仅接受整数的实现代码

    这篇文章主要介绍了HTML5数字输入仅接受整数的实现代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. amaze ui 的使用详细教程

    这篇文章主要介绍了amaze ui 的使用详细教程,本文通过多种方法给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  4. html5简介_动力节点Java学院整理

    这篇文章主要介绍了html5简介,用于指定构建网页的元素,这些元素中的大多数都用于描述网页内容,有兴趣的可以了解一下

  5. ios 8 Homescreen webapp,关闭和打开iPad停止javascript

    我有一个适用于iPad的全屏HTML5网络应用程序,并且刚刚安装了IOS8来试用它,它一切正常,直到你关闭并重新启动iPad.一旦web应用程序重新启动javascript就会停止并加载新页面不会重新启动它.在iPad上的Safari中打开同一页面时,关闭和打开iPad会继续按预期工作.其他人注意到了这个或想出了一个解决方案吗?解决方法这似乎是我在iOS8.1.1更新中解决的.

  6. iOS 6 javascript与object.defineProperty的间歇性问题

    当访问使用较新的Object.defineProperty语法定义属性的对象的属性时,有没有其他人注意到新iOS6javascript引擎中的间歇性错误/问题?https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty我正在看到javascript失败的情况,说

  7. ios – 如何使用JSExport导出内部类的方法

    解决方法似乎没有办法将内部类函数导出到javascript.我将内部类移出并创建了独立的类,它起作用了.

  8. 静音iOS推送通知与React Native应用程序在后台

    我有一个ReactNative应用程序,我试图获得一个发送到JavaScript处理程序的静默iOS推送通知.我看到的行为是AppDelegate中的didReceiveRemoteNotification函数被调用,但是我的JavaScript中的处理程序不会被调用,除非应用程序在前台,或者最近才被关闭.我很困惑的事情显然是应用程序正在被唤醒,并且它的didReceiveRemoteNotifi

  9. ios – 内存泄漏与UIWebView和Javascript

    清楚地包含一个Javascript文件到我的HTML是使UIWebView泄漏内存.当我重复使用相同的UIWebView对象时,或者每当我有内容实例化一个新的漏洞时,会出现泄漏的事实,导致我认为必须有一些JavaScript文件被loadHTMLString处理,导致泄漏.有人知道如何解决这个问题吗?

  10. iOS应用程序的UI自动化测试如何与乐器和Javascript

    从WWDC2010视频会议中了解iOS应用程序的自动化UI测试,但没有实践.从代码项目project,我们可以有一个例子.这个问题在这里听到有涉及这个的人.任何限制?解决方法我建议从AlexWollmer开始使用thisblogpost.他创建了一个非常有用的JavaScript库:tuneup_jswithtest()函数,它允许测试分离和有用的帮助者以及为自动化仪器编写测试的断言.

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部