代码的一个执行顺序
不管是什么样的编程语言,在代码执行过程中都是需要分配内存的,不同编程语言内存管理也不一样,有的需要我们手动管理,有的编程语言会自动帮我们管理内存,但不管以什么样的方式管理内存,内存的管理都会有相同的 生命周期
不同的编程语言对于第一步和第三步会有不同的实现 !
手动管理内存: 比如C、C++,包括早期的OC,都是需要手动来管理内存的申请和释放的 ( 可以调用malloc 函数申请空间使用 free 释放内存 )
自动管理内存: 比如 JavaJavaScript 、PythonSwift 、Dar t等,它们有自动帮助我们管理内存
JavaScript 自动管理内存
JavaScript通常情况下是不需要手动来管理的,JavaScript会在定义变量时为自动帮我们分配内存,但是内存分配方式是不一样的!
因为内存的大小是有限的,所以当内存不再需要的时候,我们需要对其进行释放,以便腾出更多的内存空间。
在手动管理内存的语言中,我们需要通过一些方式自己来释放不再需要的内存,比如free函数:
所以大部分现代的编程语言都是有自己的垃圾回收机制 (GC : Garbage Collection): 对于那些不再使用的对象,我们都称之为是垃圾,它需要被回收,以释放更多的内存空间;我们的语言运行环境,比如Java的运行环境JVM,JavaScript 的运行环境 js 引擎都会内存垃圾回收器(内置好了),但是这里又出现了另外一个很关键的问题:GC怎么知道哪些对象是不再使用的呢? 这里就要用到 GC的算法
JS 垃圾回收算法 —— 引用计数
当一个对象有一个引用指向它时,那么这个对象的引用就+1,当一个对象的引用为0时,这个对象就可以被销,
这个算法有一个很大的弊端就是会产生循环引用,因为他们互相引用会造成内存泄漏
var obj1 = { name : obj2 }
var obj2 = { name : obj1 }
JS 垃圾回收算法 —— 标记清除
这个算法是设置一个根对象(root object),垃圾回收器会定期从这个根开始,找所有从根开始有引用到的对象,
对于哪些没有引用到的对象,就认为是不可用的对象,这个算法可以很好的解决循环引用的问题,。
JS引擎比较广泛的采用的就是标记清除算法,当然类似于V8引擎为了进行更好的优化,它在算法的实现细节上也会结合一些其他的算法
内存泄漏
因为代码执行是要分配内存的,js 是自动帮我们管理内存的,但是可能会存在内存没有及时地回收,导致内存资源浪费情况,我们又称为内存泄漏,比如:
解决内存泄露
我们编译器有一个自动的内存清理。常见的主要是 引用记数
和 标记清除
。 谷歌浏览器主要是用标记清除,大概流程是给每一个变量添加一个标记,通过内部算法计算引用情况,当不使用的时候就会自动清除。如果遇到定时器的话,我一般会在页面关闭的时候手动清除。如果遇到循环引用,我一般会手动把变量赋值为 null 来清除