搞不定 NodeJS 内存泄漏?先从了解垃圾回收开始(1),为你保驾护航

手动管理需要开发者自己管理内存,什么时候申请内存空间,什么时候释放都需要小心处理,否则容易形成内存泄漏和指针乱飞的局面。C 语言开发是典型的需要手动管理内存的例子。

自动管理通常通过垃圾回收的机制来实现内存管理。NodeJS 中的内存管理是自动管理的。

垃圾回收

====

垃圾回收器(garbage collector,GC)通过判断对象是否还在被其他对象引用来决定是否回收该对象的内存空间。

垃圾回收之前的内存

=========

在下面的图中,有一些对象还在被其他对象使用,而有一些对象已经是完全孤立状态,没有其他对象使用它了。这些已经完全孤立状态的对象是可以被垃圾回收器回收的。

搞不定 NodeJS 内存泄漏?先从了解垃圾回收开始

垃圾回收之后的内存

=========

垃圾回收一旦开始运行,内存中的那些完全孤立(不可到达)的对象会被删除,内存空间会被释放。

搞不定 NodeJS 内存泄漏?先从了解垃圾回收开始

垃圾回收是如何工作的

==========

要搞清楚垃圾回收是如何工作的,需要先了解一些基本概念。

基本概念

====

  • 常驻集大小(resident set size):NodeJS 进程运行时占据的内存大小,通常包含:代码、栈和堆。

  • 栈(stack):包含原始类型数据和指向对象的引用数据。栈中保存着局部变量和指向堆上对象的指针或定义应用程序控制流的指针(比如函数调用等)。下面代码中,a 和 b 都保存在栈中。function add (a, b) { return a + b } add(4, 5)

  • 堆(heap):存放引用类型数据,比如对象、字符串、闭包等。下面代码中,创建的 Car 对象会被保存在堆中。function Car (opts) { this.name = opts.name } const LightningMcQueen = new Car({name: ‘Lightning McQueen’}) 对象创建后,堆内存状态如下:现在我们添加更多的对象:const SallyCarrera = new Car({name: ‘Sally Carrera’}) const Mater = new Car({name: ‘Mater’}) 堆内存状态如下:如果现在执行垃圾回收,没有任何内存会被释放,因为每个对象都在被使用(可到达)。现在我们修改代码,如下:function Engine (power) { this.power = power } function Car (opts) { this.name = opts.name this.engine = new Engine(opts.power) } let LightningMcQueen = new Car({name: ‘Lightning McQueen’, power: 900}) let SallyCarrera = new Car({name: ‘Sally Carrera’, power: 500}) let Mater = new Car({name: ‘Mater’, power: 100}) 堆内存状态变成:如果我们不在使用 Mater 的话,通过 Mater = undefined 删除了对内存中对象的引用,则内存状态变化为:此时内存中的 Mater 不再被其他对象使用了(不可达),当垃圾回收运行的时候,Mater 对象会被回收,其占据的内存会被释放。

  • 对象的浅层大小(shallow size of an object):对象本身占据的内存大小。

  • 对象的保留大小(retained size of an object):删除对象及其依赖对象后释放的内存大小

垃圾回收器是如何工作的

===========

NodeJS 的垃圾回收通过 V8 实现。大多数对象的生命周期都很短,而少数对象的寿命往往更长。为了利用这种行为,V8 将堆分成两个部分,年轻代(Young Generation)老年代(Old Generation)

年轻代

===

新的内存需求都在年轻代中分配。年轻代的大小很小,在 1 到 8 MB 之间。在年轻代中内存分配非常便宜,V8 在内存中会逐个为对象分配空间,当到达年轻代的边界时,会触发一次垃圾回收。

V8 在年轻代会采用 Scavenge 回收策略。Scavenge 采用复制的方式进行垃圾回收。它将内存一分为二,每一部分空间称为 semispace。这两个空间,只有一个空间处于使用中,另一个则处于闲置。使用中的 semispace 称为 「From 空间」,闲置的 semispace 称为 「To 空间」。

年轻代的内存分配过程如下:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后的最后

面试题千万不要死记,一定要自己理解,用自己的方式表达出来,在这里预祝各位成功拿下自己心仪的offer。
需要完整面试题的朋友可以点击蓝色字体免费获取

大厂面试题

面试题目录

[外链图片转存中…(img-tlWNJobN-1712367428971)]

[外链图片转存中…(img-hKigCK2J-1712367428971)]

[外链图片转存中…(img-w8aUCGWm-1712367428971)]

  • 22
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值