首先,咱们须要对内存管理概念有一个基本的认识。内存管理是指操做系统如何进行内存的分配和回收的机制。早期的计算机语言,好比C, 它经过malloc, free函数来向操做系统请求内存和释放内存。优势是内存分配和释放的效率很高;缺点主要表如今对于复杂的系统,存在着大量的内存分配和释放操做。程序员很容易不当心忘记释放内存,从而形成内存的泄露,对于长期运行的软件来说,系统的内存会逐渐被吃光。 所以,更新的编程语言,好比JAVA, C#, 都提供了所谓“垃圾回收的机制”,运行时自身会运行相应的垃圾回收机制。程序员只须要申请内存,而不须要关注内存的释放。垃圾回收器(GC)会在适当的时候将已经终止生命周期的变量的内存给释放掉。(https://www.zhihu.com/question/19831128/answer/13097702)html
几种垃圾回收机制算法程序员
1.引用计数算法(Reference Counting)算法
每一个对象计算指向它的指针的数量,当有一个指针指向本身时计数值加1;当删除一个指向本身的指针时,计数值减1,若是计数值减为0,说明已经不存在指向该对象的指针了,因此它能够被安全的销毁了。算法特色:1)须要单独的字段存储计数器,增长了存储空间的开销;2)每次赋值都须要更新计数器,增长了时间开销;3)垃圾对象便于辨识,只要计数器为0,就可做为垃圾回收;4)及时回收垃圾,没有延迟性;5)不能解决循环引用的问题。编程
在低版本IE中常常会出现内存泄露,不少时候就是由于其采用引用计数方式进行垃圾回收。好比对象A有一个属性指向对象B,而对象B也有有一个属性指向对象A,这样相互引用浏览器
function test(){ var a={}; var b={}; a.prop=b; b.prop=a; }
a和b的引用次数都是2,即便在test()执行完成后,两个对象都已经离开环境,在标记清除的策略下是没有问题的,离开环境的就被清除,可是在引用计数策略下不行,由于这两个对象的引用次数仍然是2,不会变成0,因此其占用空间不会被清理,若是这个函数被屡次调用,这样就会不断地有空间不会被回收,形成内存泄露。安全
2. 标记-清除(Mark-Sweep)算法编程语言
Mark-Sweep依赖于对全部存活对象进行一次全局遍从来肯定哪些对象能够回收,遍历的过程从根出发,找到全部可达对象,除此以外,其它不可达的对象就是垃圾对象,可被回收。整个过程分为两个阶段:标记阶段找到全部存活对象;清除阶段清除全部垃圾对象。Lua就采用了mark-sweep的垃圾回收机制。大部分浏览器也都是使用这种方式进行垃圾回收,区别在于如何标记及垃圾回收间隔而已 。函数
优势:性能
相比较引用计数算法,标记-清除算法能够很是天然的处理环形引用问题,spa
另外在建立对象和销毁对象时时少了操做引用计数值的开销
缺点:
标记-清除算法是一种“中止-启动”算法,在垃圾回收器运行过程当中,应用程序必须暂时中止
标记-清除算法在标记阶段须要遍历全部的存活对象,会形成必定的开销
在清除阶段,清除垃圾对象后会形成大量的内存碎片。
3. 标记-缩并算法(解决内存碎片)
整个过程能够描述为
* 标记全部的存活对象;
* 经过从新调整存活对象位置来缩并对象图;
* 更新指向被移动了位置的对象的指针。
标记-压缩算法最大的难点在于如何选择所使用的压缩算法,若是压缩算法选择很差,将会致使极大的程序性能问题,如致使Cache命中率低等。通常来讲,根据压缩后对象的位置不一样,压缩算法能够分为如下三种:
任意:移动对象时不考虑它们原来的次序,也不考虑它们之间是否有互相引用的关系。
线性:尽量的将原来的对象和它所指向的对象放在相邻位置上,这样能够达到更好的空间局部性。
滑动:将对象“滑动”到堆的一端,把存活对象之间的自由单元“挤出去”,从而维持了分配时的原始次序。
4. 节点拷贝算法(解决内部碎片)
节点拷贝算法是把整个堆分红两个半区(From,To), GC的过程其实就是把存活对象从一个半区From拷贝到另一个半区To的过程,而在下一次回收时,两个半区再互换角色。在移动结束后,再更新对象的指针引用
参考 http://blog.csdn.net/sinat_36246371/article/details/53002209
垃圾回收器周期性运行,若是分配的内存很是多,那么回收工做也会很艰巨,肯定垃圾回收时间间隔就变成了一个值得思考的问题。IE6的垃圾回收是根据内存分配量运行的,当环境中存在256个变量、4096个对象、64k的字符串任意一种状况的时候就会触发垃圾回收器工做,看起来很科学,不用按一段时间就调用一次,有时候会不必,这样按需调用不是很好吗?可是若是环境中就是有这么多变量等一直存在,如今脚本如此复杂,很正常,那么结果就是垃圾回收器一直在工做,这样浏览器就无法儿玩儿了。
微软在IE7中作了调整,触发条件再也不是固定的,而是动态修改的,初始值和IE6相同,若是垃圾回收器回收的内存分配量低于程序占用内存的15%,说明大部份内存不可被回收,设的垃圾回收触发条件过于敏感,这时候把临街条件翻倍,若是回收的内存高于85%,说明大部份内存早就该清理了,这时候把触发条件置回。这样就使垃圾回收工做职能了不少。
同C# 、Java同样咱们能够手工调用垃圾回收程序,可是因为其消耗大量资源,并且咱们手工调用的不会比浏览器判断的准确,因此不推荐手工调用垃圾回收。
转自http://www.cnblogs.com/dolphinX/p/3348468.html