V8引擎的内存收回

短命女 2023-03-01 03:29 122阅读 0赞

V8引擎的内存收回

#

前言

JS语言不像C/C++, 让程序员自己去开辟或者释放内存,而是类似Java,采用自己的一套垃圾回收算法进行自动的内存管理。

我们知道对于栈内存而言,当ESP指针下移,也就是上下文切换之后,栈顶的空间会自动被回收。但对于堆内存而言就比较复杂了,我们下面着重分析堆内存的垃圾回收。

#

V8内存限制

在其他的后端语言中,如Java/Go, 对于内存的使用没有什么限制,但是JS不一样,V8只能使用系统的一部分内存,具体来说,在64位系统下, V8最多只能分配1.4G, 在 32 位系统中,最多只能分配0.7G。

#

V8内存限制的原因

  • JS是单线程运行的,这意味着一旦进入到垃圾回收,那么其它的各种运行逻辑都要暂停
  • 垃圾回收是非常耗时间的操作

#

V8内存限制的调整

  1. // 老生代 单位是MB
  2. node --max-old-space-size=2048 xxx.js
  3. // 新生代 单位是KB
  4. node --max-new-space-size=2048 xxx.js
  5. 复制代码

#

V8内存回收

V8把堆内存分成了两部分进行处理——新生代内存和老生代内存。顾名思义,新生代就是临时分配的内存,存活时间短,老生代是常驻内存,存活的时间长。V8的堆内存,也就是两个内存之和。

根据这两种不同种类的堆内存,V8采用了不同的回收策略,来根据不同的场景做针对性的优化。

#

新生代内存的回收

首先将新生代内存空间一分为二,分别是From和To,其中From部分表示正在使用的内存,To是目前闲置的内存。

当进行垃圾回收时,V8将From部分的对象检查一遍,如果是存活对象那么复制到To内存中(在To内存中按照顺序从头放置的),如果是非存活对象直接回收即可。

当所有的From中的存活对象按照顺序进入到To内存之后,From和To两者的角色对调,From现在被闲置,To为正在使用,如此循环。

上述描述的垃圾回收的过程也叫Scavenge算法。

#

在To内存中按照顺序从头放置的?

在To内存中按照顺序从头放置的,这是为了应对这样的场景的。

当内存中有很多零零散散未分配对象的空间的时候,可能稍微大点的对象就没有办法进行空间分配,这种零散的空间也叫做内存碎片。

为了解决这样的问题,Scavenge算法将对象整整齐齐的分配到连续的内存空间。

#

Scavenge算法的优缺点

内存只能使用新生代内存的一半,但是它只存放生命周期短的对象,这种对象一般很少,因此时间性能非常优秀。

#

老生代内存的回收

新生代中的变量如果经过多次回收后依然存在,那么就会被放入到老生代内存中,这种现象就叫晋升。

发生晋升的原因有两种,一种是已经经历过一次 Scavenge 回收,另一种是To(闲置)空间的内存占用超过25%。

那么对于老生代而言,究竟是采取怎样的策略进行垃圾回收的呢?

请阅读以前的文章《秒懂js的垃圾回收》 。

发表评论

表情:
评论列表 (有 0 条评论,122人围观)

还没有评论,来说两句吧...

相关阅读

    相关 V8引擎内存收回

    V8引擎的内存收回 前言 JS语言不像C/C++, 让程序员自己去开辟或者释放内存,而是类似Java,采用自己的一套垃圾回收算法进行自动的内存管理。 我们知

    相关 谷歌v8引擎详解

    前言   JavaScript绝对是最火的编程语言之一,一直具有很大的用户群,随着在服务端的使用(NodeJs),更是爆发了极强的生命力。编程语言分为编译型语言和解释型语

    相关 深入V8引擎-AST(1)

      没办法了,开坑吧,接下来的几篇会讲述JavaScript字符串源码在v8中转换成AST(抽象语法树)的过程。   JS代码在V8的解析只有简单的几步,其中第一步就是将源字

    相关 深入V8引擎-AST(5)

    懒得发首页了,有时候因为贴的代码太多会被下,而且这东西本来也只是对自己学习的记录,阅读体验极差,所以就本地自娱自乐的写着吧! 由于是解析字符串,所以在开始之前介绍一下词法结构

    相关 v8引擎详解

    前言 `JavaScript`绝对是最火的编程语言之一,一直具有很大的用户群,随着在服务端的使用(`NodeJs`),更是爆发了极强的生命力。编程语言分为编译型语言和解释