js 内存管理与 js 垃圾

大家好,今天分享的主题是内存管理机制。本次分享将分以下三个部分进行介绍:

js内存管理和js垃圾

关于内存管理机制,相信大家都知道一些。下面简单介绍一下js内存管理和js垃圾。内存管理由 JS 自动操作,不需要人工参与。这些内存管理包括以下三项:

js垃圾是指对象未被引用,无法从root访问对象的时间,可以称为js垃圾。其他部分,包括引用和可达对象,大家肯定都很熟悉了,这里就不多说了。现在让我们谈谈GC算法。

GC算法

GC算法其实就是在内存中寻找垃圾,释放和回收空间。这里所说的垃圾是指算法认为程序不再需要使用的对象,以及程序中无法访问的对象。

说起GC算法,这是一个比较概念的内容,所以简单总结一下。GC是一种垃圾收集器机制,它在内存中找到垃圾以释放空间和回收空间。算法是在工作时寻找和回收的规则。常见的 GC 算法包括引用计数、标记清除、标记排序和分代回收。

引用计数

图片[1]-js 内存管理与 js 垃圾-唐朝资源网

引用计数以前主要用在IE8以下的浏览器中,现在浏览器已经不用了,这里只做简单介绍。引用计数的基本原理是记录和跟踪每个值被引用的次数。被引用时计数加一,释放时减一。当该值为零时,表示该值所在的内存不再被使用,因此占用的空间被释放。. 引用计数的好处是实时监控引用的数量,因此可以及时收集垃圾回收,从而最大限度地减少程序暂停时间。但也正是因为它一直在运行,所以资源消耗和时间开销都很大,循环引用的对象无法恢复。

标记清楚

标记清除分为标记和清除两个阶段。核心思想是遍历所有对象,找到被标记的活动对象,也就是上面提到的可达对象,清除未标记的对象,回收未标记对象的空间。

图片[2]-js 内存管理与 js 垃圾-唐朝资源网

上图是一个简单的搜索流程图。其中,左边的A、B、C、D、E代表可以找到的对象,右边的a1、b1代表循环引用的对象。其中,a1为引用计数,由于引用计数一直在运行,循环引用对象的缺点无法挽回,可以逆向找到循环引用对象。

这也是mark-sweep的优点,可以解决对象循环的引用回收问题。但是,mark-的缺点是空间碎片化,垃圾对象不能及时回收。因为需要先标记然后清除,不能像引用计数一样实时监控值,所以不能最大限度的利用空间。下图简要介绍了标记删除的空间碎片特征。

图片[3]-js 内存管理与 js 垃圾-唐朝资源网

图片[4]-js 内存管理与 js 垃圾-唐朝资源网

标记

如上所述,标记清除存在空间碎片化的缺点,标记排序优化了这个缺点。顾名思义,标记清理是对标记删除的增强。标记阶段标记排序的操作与标记清除相同,但在清除阶段,先进行排序,再进行清除。这种方法可以有效减少碎片空间。与mark-sweep 一样,mark-sweep 不会实时收集垃圾对象。

通过下面三张图,我们对标签排序有了一个简单直观的认识。

图片[5]-js 内存管理与 js 垃圾-唐朝资源网

可以看出,在垃圾回收之前,活动空间和非活动空间是混合在一起的。确定回收后,标记和排序会对空间进行分类,将活动空间和非活动空间组织在一起,形成下图的结果:

图片[6]-js 内存管理与 js 垃圾-唐朝资源网

图片[7]-js 内存管理与 js 垃圾-唐朝资源网

标记清零后,可以避免回收操作,避免大量碎片化空间,最大限度地利用空间。

图片[8]-js 内存管理与 js 垃圾-唐朝资源网

看完GC算法,以V8引擎为例,我们来看看GC算法在JS垃圾回收中的使用。

V8 引擎的垃圾收集

V8是目前比较主流的执行引擎。采用实时编译,处理速度快。V8 的内存是有限的。比如64位操作系统的上限是1.4T,下限是700M,32位操作系统的上限和下限分别是64M和32M。

图片[9]-js 内存管理与 js 垃圾-唐朝资源网

V8采用分代回收的垃圾回收策略,将内存分为新生代和老年代两种,针对不同的对象采用不同的对应算法。

图片[10]-js 内存管理与 js 垃圾-唐朝资源网

图片[11]-js 内存管理与 js 垃圾-唐朝资源网

上图是V8的内存分配示意图。可以看出V8内存空间分为两部分。左边的from和to是新一代,占用空间比较小(32M|16M)。这里的新生代是指生存时间较短的存储区域。右边红色部分是存活时间较长的老年代存储区。

V8中有五种常用的GC算法:

其中,新生代使用复制算法和标记排序进行垃圾收集,老一代使用标记清除、标记排序和增量标记进行垃圾收集。

图片[12]-js 内存管理与 js 垃圾-唐朝资源网

V8 新一代对象回收实现

图片[13]-js 内存管理与 js 垃圾-唐朝资源网

上图是V8新生代对象回收的实现图,它使用复制算法和标签排序相结合的方式进行垃圾回收。新生代内存区域中两个大小相等的空间,From代表存储活动对象的已用空间,To代表空闲空间。V8 的新一代对象回收是通过标记和排序完成排序后将对象复制到 To,然后交换 To 和 From 之间的空间,释放排序后的无用对象占用的空间。请注意,将整理对象复制到 To 时可能会发生提升。提升是指将年轻代对象移动到老年代存储。升职通常有两个条件。一是可以提升经过一轮GC后还活着的新生代对象,

V8老年代对象回收实现

V8老年代的回收过程采用标记清除、标记排序和标记增量相结合的方式。一般垃圾回收时,通过标记和清除的方式回收垃圾空间。但是当新生代移动到老年代,老年代内存不足时,通过标记排序进行空间优化,使用增量标记进行效率优化。

图片[14]-js 内存管理与 js 垃圾-唐朝资源网

标记增量实际上是标记标记操作以使时间合理的一种方式。这句话可能有点混乱。简单来说就是在垃圾回收的时候,让标记系统在标记的时候划分不同的时间段,分别标记和执行,让两者的操作有间隔,从而优化时间安排,这样会让页面感觉更流畅.

© 版权声明
THE END
喜欢就支持一下吧
点赞14赞赏 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容