javascript篇-----垃圾收集和内存问题

垃圾收集 

  javascript具有自动垃圾收集机制,也就是说,执行环境会负责管理代码执行过程中使用的内存。这种垃圾收集机制的原理其实很简单:找到那些不再继续使用的变量,然后释放其占用的内存。为此,垃圾收集器会按照固定的时间间隔周期性的执行这一操作。

  下面我们来分析一下函数中局部变量的正常生命周期。局部变量只在函数执行的过程中存在。而在这个过程中,会为局部变量在栈内存上分配相应的空间,以便存储它们的值。然后在函数中使用这些变量,直至函数执行结束。此时,局部变量就没有存在的必要了。因此可以释放它们的内存以供将来使用。在这种情况下,很容易判断变量是否还有存在的必要。但并非所有的情况下都这么容易就能得到结论。垃圾收集器必须跟踪哪个变量有用哪个变量没用,对于不再有用的变量打上打上标记,以备将来收回其占用的内存。用于标识无用变量的策略可能因实现而异,但具体到浏览器中的实现,则通常有两种策略:标记清除和引用计数。

标记清除

  javascript中最常用的垃圾收集方式就标记清除。当变量进入环境时,就将这个变量标记为“进入环境”。从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到它们。而当变量离开环境时,则将其标记为“离开环境”。

  垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记。然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记。而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后,垃圾收集器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。

引用计数

  另一种不太常见的垃圾收集策略叫做引用计数。引用计数的含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是1。如果同一个值又被赋给另一个变量,则该值的引用次数加1。相反,如果包含对这个值的引用的变量又取得了另外一个值,则这个值的引用次数减1。当这个值的引用次数变为0时,则说明没有办法在访问这个值了,因而就可以将其占用的内存空间回收回来。这样,当垃圾收集器下次在运行时,它就会释放那些引用次数为零的值所占用的内存。

 内存问题和管理内存

  javascript在进行内存管理以及垃圾收集时面临的问题还是有点与众不同的。其中最主要的一个问题,就是分配给Web浏览器的可用内存数量通常要比分配给桌面应用程序的少。这样做的目的主要是出于安全方面的考虑,目的是防止运行的javaScript的网页耗尽全部全通内存而导致系统崩溃。内存限制问题不仅会影响给变量分配内存,同时还会影响调用栈以及在一个线程中能够同时执行的语句数量。

  因此,确保占用最少的内存可以让页面获得最好的性能。而优化内存占用的最佳方式,就是为执行中的代码只保存必要的数据。一般数据不在有用,最好通过将其值设置为null来释放其引用——这个做法叫做解除引用。这个做法适用于大多数全局变量和全局对象的属性。局部变量会在他们离开执行环境的时被解除引用。不过,解除一个值的引用并不意味着自动回收该值所占用的内存。解除引用的真正作用时让值脱离执行环境,以便垃圾收集器下次运行时将其回收。

 1 {
 2   function createPerson (name) {
 3     var localPerson = new Object();
 4     localPerson.name = name;
 5     return localPerson;
 6   }
 7   // 声明全局变量globalPerson
 8   var globalPerson = createPerson('lili');
 9   // 手工解除globalPerson引用
10   globalPerson = null;
11 }

 

posted @ 2017-10-07 13:59  笛子Hardy  阅读(81)  评论(0编辑  收藏  举报