js的垃圾收集机制之理解
我们先了解一下什么是内存泄漏?
我们创建基本类型、对象、函数……所有这些都需要内存。程序的运行需要内存,只要程序提出要求,操作系统或者运行是就必须供给内存。所谓的内存泄漏简单来说是不再用到的内存,没有及时释放
举几个例子:
比如使用EventBus,肯定是要执行register(),那么在Fragment或Activity finish的时候,一定不要忘记执行unregister()方法
如果两个对象相互引用,尽管他们已不再使用,垃圾回收不会进行回收,导致内存泄露。
垃圾回收机制
- 什么是垃圾回收机制?
在C语言中,开发人员需要可以手动控制内存的申请和回收,但是在Java、C#、JavaScript语言中,所有的内存分配以及回收都会由垃圾回收器自动完成
JavaScript垃圾回收的机制很简单:找出不再使用的变量,然后释放掉其占用的内存,但是这个过程不是时时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行
- 垃圾回收机制的作用和好处
为了避免内存泄漏
-
垃圾回收机制的场景
-
代码示例
function test1(){
var i ={name:'nyf'};
}
function test2(){
var i ={name:'nyf'};
return i;
}
var m1 = test1();
var m2 = test2();
一般来说在e.g.1中,当 test1调用时,进入 test1 的环境,那么内存中会开辟存放 {name:’nyf’} 对象的内存,当调用结束后,出了 test1 的环境,那么该内存会被JS引擎中的垃圾回收器自动释放其内存。
在test2中,对象被返回,并且被变量 m2 所指向,所以虽然说在调用完 test2 后出了其环境,但是由于m2仍然持续着对对象的链接关系,所以该对象不会被释放。
变量的生命周期
当一个变量的生命周期结束之后它所指向的内存就应该被释放。JS有两种变量,全局变量和在函数中产生的局部变量。局部变量的生命周期在函数执行过后就结束了,此时便可将它引用的内存释放(即垃圾回收),但全局变量生命周期会持续到浏览器关闭页面。
内存分配策略:
静态分配:主要存放静态数据,全局 static 数据 和 常量。 且该块内存在编译的时候已经确定了,而且在程序运行期间都是存在的
栈区:当方法被执行的时候,即他会被放在栈的顶部,且方法内的局部变量都会在栈内被创建,并且在方法执行完后回收,因为栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
堆区:又称为动态内存分配,主要储存对象(即new出来的对象),如果存在不使用的对象,就可以GC掉。