资讯专栏INFORMATION COLUMN

内存管理之垃圾回收机制

buildupchao / 2683人阅读

摘要:一内存生命周期分配需要的内存初始化值时使用分配的内存不需要时将其内存释放垃圾回收器注意全局变量的生命周期直至浏览器卸载页面才会结束。

一、内存生命周期

1、分配需要的内存(初始化值时)
2、使用分配的内存
3、不需要时将其内存释放(垃圾回收器)
注意:
(1)全局变量的生命周期直至浏览器卸载页面才会结束。
(2)局部变量只在函数的执行过程中存在,而在这个过程中会为局部变量在栈或堆上分配相应的空间,以存储它们的值,然后再函数中使用这些变量直至函数结束局部变量就没有存在必要了,可以释放它们占用的内存

二、垃圾回收机制 1、引用计数垃圾收集

(1)算法原理
通过在对象头中分配一个空间来保存该对象被引用的次数。如果该对象被其它对象引用,则它的引用计数加一,如果删除对该对象的引用,那么它的引用计数就减一,当该对象的引用计数为0时,那么该对象就会被回收。
(2)算法理解

var p = new String("abc"); // 分配所需内存并且被p引用 abc这个字符串对象的引用计数值为1.

p = null; // 去除abc字符串对象的引用,abc字符串对象的引用计数减1

重点理解
1、当对象的引用发生变化时,首先对原来引用对象的计数减一,再对新的引用对象的计数加一

var p = new String("abc");
var q = new String("efd");
p = q;

2、当某个对象的引用计数减为0时,collector需要递归遍历它所指向的所有域,将它所有域所指向的对象的引用计数都减一,然后才能回收当前对象。在递归过程中,引用计数为0的对象也都将被回收,并把该对象的内存块加入空闲链表中

var p = {
  phone:new String("1592xxxx"),
  address:new String("1130 kifer rd")
}
p = null;

3、循环引用

function f(){
  var o = {};
  var o2 = {};
  o.a = o2; // o 引用 o2
  o2.a = o; // o2 引用 o

  return "azerty";
}

f();

(3)触发时机
引用计数垃圾收集机制在引用计数变化为0时即刻发生,而且只针对某一个对象以及它所依赖的其它对象。所以,我们一般也称呼引用计数垃圾收集为直接的垃圾收集机制

2、标记-清除算法

(1)算法原理
这个算法把“对象是否不再需要”简化定义为“对象是否可以获得”。

标记阶段是把所有活动对象都做上标记的阶段。清除阶段是把那些没有标记的对象,也就是非活动对象回收的阶段。通过这两个阶段,就可以令不能利用的内存空间重新得到利用

这个算法假定设置一个叫做根(root)的对象(在Javascript里,根是全局对象)。垃圾回收器将定期从根开始,找所有从根开始引用的对象,然后找这些对象引用的对象……从根开始,垃圾回收器将找到所有可以获得的对象和收集所有不能获得的对象。

(2)算法理解

var teacher = {name:"Mary",age:35};
var student = {
                stu1:{name:"Amy",age:13},
                stu2:{name:"Dai",age:15}
              }

标记阶段

// 标记阶段伪代码
// 进行标记阶段的处理
mark_phase(){
 for(r : $roots)
     mark(*r)
}
// 递归地标记通过指针数组能访问到的对象。这样就能把所有活动对象都标记上了。

 mark(obj){
   if(obj.mark == FALSE)
     obj.mark = TRUE
     for(child : children(obj))
       mark(*child)
 }

清除阶段

// 标记清除伪代码
 1 sweep_phase(){
 2   sweeping = $heap_start // 从堆首地址开始
 3   while(sweeping < $heap_end) // 遍历每个标志位
 4     if(sweeping.mark == TRUE) // 如果遍历到已标记元素
 5       sweeping.mark = FALSE // 将标记清除
 6     else // 没有遍历到
 7       sweeping.next = $free_list // 将其插在空闲链表头部
 8       $free_list = sweeping // 将空闲链表指针指向所有空闲链
 9   sweeping += sweeping.size // 继续进行查找
10 }

(3)触发时机
垃圾收集器会按照固定的时间间隔或代码执行中预定的收集时间,周期性地执行

参考文章
内存管理
引用计数算法
GC-标记清除算法
深入理解作用域链(超赞)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99061.html

相关文章

  • 《JavaScript 闯关记》垃圾回收内存管理

    摘要:内存回收此时,局部变量就没有存在的必要了,因此可以释放它们的内存以供将来使用。局部变量会在它们离开执行环境时自动被解除引用,如下面这个例子所示手工解除的引用由于局部变量在函数执行完毕后就离开了其执行环境,因此无需我们显式地去为它解除引用。 JavaScript 具有自动垃圾收集机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存。而...

    Sleepy 评论0 收藏0
  • PHP引用计数内存管理机制垃圾回收机制

    摘要:引入的同步算法传统上,像以前的用到的引用计数内存机制,无法处理循环引用的内存泄漏。然而使用文章引用计数系统中的同步周期回收中的同步算法,解决了这个内存泄漏问题,这种算法就是的垃圾回收机制。 引用赋值 $a = apple; $b = &$a; 上述代码中,我将一个字符串赋值给变量a,然后将a的引用赋值给了变量b。显然,这个时候的内存指向应该是这样的: $a -> apple

    psychola 评论0 收藏0
  • JS专题垃圾回收

    摘要:如果没有引用指向该对象零引用,对象将被垃圾回收机制回收。经过增量标记改进后,垃圾回收的最大停顿时间可以减少到原来的左右。解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。 前言 在讲 JS 的垃圾回收(Garbage Collection)之前,我们回顾上一篇《JS专题之memoization》,memoization 的原理是以参数作为 key,函数结果作为 v...

    liujs 评论0 收藏0
  • Node.js内存管理和V8垃圾回收机制

    摘要:垃圾回收内存管理实践先通过一个来看看在中进行垃圾回收的过程是怎样的内存泄漏识别在环境里提供了方法用来查看当前进程内存使用情况,单位为字节中保存的进程占用的内存部分,包括代码本身栈堆。 showImg(https://segmentfault.com/img/remote/1460000019894672?w=640&h=426);作者 | 五月君Node.js 技术栈 | https:...

    JowayYoung 评论0 收藏0
  • Java性能优化垃圾回收机制

    摘要:年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。年老代在年轻代中经历了次垃圾回收后仍然存活的对象,就会被放到年老代中。什么情况下触发垃圾回收由于对象进行了分代处理,因此垃圾回收区域时间也不一样。 [TOC] 与C/C++相比,java语言不需要程序员直接控制内存回收,java程序的内存分配和回收都是由JRE在后台自动进行,JRE会负责回收那些不再使用的内存,这种机制被称为垃圾...

    philadelphia 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<