一些思考

回收

nodejs垃圾回收

跟浏览器js不同,  以下代码会找出内存泄露

var theThing = null
var replaceThing = function () {
var originalThing = theThing
var unused = function () {
if (originalThing)
console.log("hi")
}
theThing = {
longStr: new Array(1000000).join('*'),
someMethod: function () {
console.log(someMessage)
}
};
};
setInterval(replaceThing, 1000)

  

这篇文章中,你可以学到 Node.js 的垃圾回收 (以下简称 GC ) 是怎么工作的,你写下的代码在后台发生了什么,以及内存是如何释放的。

Node.js 应用中的内存管理

每个应用都需要内存才能正常运行。内存管理能动态的分配内存块给需要的程序,在不需要时释放掉,以便能重复使用。

应用级的内存管理可以是手动或自动的。而自动内存管理往往涉及到 GC。

下面的代码片段展示了在 C 中如何使用手动内存管理分配内存:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main() {
 
char name[20];
char *description;
 
strcpy(name, "RisingStack");
 
// memory allocation
description = malloc( 30 * sizeof(char) );
 
if( description == NULL ) {
fprintf(stderr, "Error - unable to allocate required memory\n");
} else {
strcpy( description, "Trace by RisingStack is an APM.");
}
 
printf("Company name = %s\n", name );
printf("Description: %s\n", description );
 
// release memory
free(description);
}

手动内存管理中,开发者有责任释放闲置的内存,这种内存管理方式可能会造成下面几个问题:

  • 内存泄露,当从不释放使用过的内存时发生
  • 野指针,当对象被释放时,而原来的指针仍继续使用。在其他数据覆盖写入或读取敏感信息时会造成严重的安全问题

值得庆幸的是,Node.js 附带了一个垃圾回收器,你不需要去手动管理内存分配

GC 的理念

GC 是一种自动管理应用内存的方法。GC 的工作是回收被未使用的对象所占用的内存。它在 1959 年首次应用于 John McCarthy 创造的 LISP 中。

GC 判断对象不再使用的方式是 没有其他的对象引用它们。 a = o, a = null,   o就回收了

GC 前的内存

你的内存看上去如下图所示,如果你有一些互相引用的对象以及一些没有任何引用的对象。

这些没有引用的对象会在 GC 运行 时被回收。

memory-state-before-node-js-garbage-collection

GC 后的内存

当 GC 运行起来,无法访问 (没有引用)  的对象会被删除,同时释放掉相应的内存空间。

memory-state-after-node-js-garbage-collection

GC 的优点

  • 防止了野指针 bug
  • 不用担心内存的二次释放
  • 避免了一些类型的内存泄露

当然,使用 GC 不能解决你所有的问题,而且它也不是内存管理的银弹。

使用 GC 时需要注意的事项
  • 性能影响 - GC 会消耗计算能力去决定什么对象应该释放
  • 无法预测的停顿 - 现代 GC 实现尝试去避免 stop-the-world 的回收方式

Node.js GC & 内存管理实践

实践出真知,所以我打算通过几段不同的代码向你展示内存中发生了什么

栈上包含了局部变量和 指向堆上对象 或 指  向应用程序控制流程的指针。

在以下示例中,a和b将会被放置在栈中

function add (a, b) {
    return a + b
}
 
add(4, 5)

堆专门用于存储引用类型对象,如字符串?和对象。

在以下示例中,Car 对象将会被放置在栈中

function Car (opts) {
this.name = opts.name
}
 
const LightningMcQueen = new Car({name: 'Lightning McQueen'})

在这之后,内存看起来像这个样子

node-js-garbage-collection-first-step-object-placed-in-memory-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'})

node-js-garbage-collection-second-step-more-elements-added-to-the-heap

如果GC现在运行,由于根有对每个对象的引用,没有对象会被释放。

让我们添加一些零件到我们的汽车里 (Car 对象) 使它更有趣一点

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})

node-js-garbage-collection-assigning-values-to-the-objects-in-heap

如果我们不再使用 Mater,但是重新定义并对它赋值 (如Mater = undefined) 会发生什么?

node-js-garbage-collection-redefining-values

结果就是,无法从根上访问 Master 对象。所以当下一次 GC 运行时,它将会被释放:

node-js-garbage-collection-freeing-up-unreachable-object

现在我们了解了 GC 预期行为的基础,那让我们看看它在 V8 中是如何实现的。

GC 方法

在我们之前的一篇文章中,我们讨论了 Node.js GC 方法是如何工作的,所以我强烈建议去阅读这篇文章。

  • 新生区和老生区
  • 新生代 (Young Generation)
  • Scavenge 和 标记删除

一个真实的例子 — The Meteor Case-Study

在 2013 年,Meteor 的作者宣布了他们碰到的关于内存泄露的发现 ?,问题代码如下所示:

var theThing = null  
var replaceThing = function () {
var originalThing = theThing
var unused = function () {
if (originalThing)
console.log("hi")
}
theThing = {
longStr: new Array(1000000).join('*'),
someMethod: function () {
console.log(someMessage)
}
};
};
setInterval(replaceThing, 1000)
 

node 垃圾回收的更多相关文章

  1. 超详细的node/v8/js垃圾回收机制

    前言 垃圾回收器是一把十足的双刃剑.其好处是可以大幅简化程序的内存管理代码,因为内存管理无需程序员来操作,由此也减少了(但没有根除)长时间运转的程序的内存泄漏.对于某些程序员来说,它甚至能够提升代码的 ...

  2. 深入理解Node.js中的垃圾回收和内存泄漏的捕获

    深入理解Node.js中的垃圾回收和内存泄漏的捕获 文章来自:http://wwsun.github.io/posts/understanding-nodejs-gc.html Jan 5, 2016 ...

  3. Node内存限制与垃圾回收

    对象分配 所有的JS对象都是通过堆来进行分配的.使用process.memoryUsage()查看使用情况Node.js 中文网文档 process.memoryUsage() { rss: , he ...

  4. Java内存模型与垃圾回收

    1.Java内存模型 Java虚拟机在执行程序时把它管理的内存分为若干数据区域,这些数据区域分布情况如下图所示: 程序计数器:一块较小内存区域,指向当前所执行的字节码.如果线程正在执行一个Java方法 ...

  5. ubifs核心功能 -- 垃圾回收

    可回收空间的分类 垃圾回收的目的是再利用(回收后的空间大小能写入有效的node),如果再利用的价值越低,其回收的必要性越低.为了进行有效的垃圾回收,UBIFS对可回收空间做了2个层次的水线划分: 死空 ...

  6. .Net 垃圾回收和大对象处理

    CLR垃圾回收器根据所占空间大小划分对象.大对象和小对象的处理方式有很大区别.比如内存碎片整理 —— 在内存中移动大对象的成本是昂贵的,让我们研究一下垃圾回收器是如何处理大对象的,大对象对程序性能有哪 ...

  7. 浅谈Chrome V8引擎中的垃圾回收机制

    垃圾回收器 JavaScript的垃圾回收器 JavaScript使用垃圾回收机制来自动管理内存.垃圾回收是一把双刃剑,其好处是可以大幅简化程序的内存管理代码,降低程序员的负担,减少因 长时间运转而带 ...

  8. 浅谈V8引擎中的垃圾回收机制

    最近在看<深入浅出nodejs>关于V8垃圾回收机制的章节,转自:http://blog.segmentfault.com/skyinlayer/1190000000440270 这篇文章 ...

  9. 【python进阶】Garbage collection垃圾回收1

    前言 GC垃圾回收在python中是很重要的一部分,同样我将分两次去讲解Garbage collection垃圾回收,此篇为Garbage collection垃圾回收第一篇,下面开始今天的说明~~~ ...

随机推荐

  1. Java-性能调优实战(jps、jstack)

    找最耗CPU的线程 1. 找出java进程 [ ~]# jps 9939 Resin 9874 WatchdogManager 9926 Jps 2. 找java进程下所有的线程 [ ~]# top ...

  2. 20145328 《Java程序设计》实验三实验报告

    20145328 <Java程序设计>实验三实验报告 实验名称 Java敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 实验步骤 (一)敏捷开发与XP 敏捷开发是一种以人为 ...

  3. python爬虫之新浪微博登录

    fiddler 之前了解了一些常见到的反爬措施,JS加密算是比较困难,而微博的登录中正是用JS加密来反爬,今天来了解一下. 分析过程 首先我们去抓包,从登录到微博首页加载出来的过程.我们重点关注一下登 ...

  4. 深度学习笔记(一):logistic分类【转】

    本文转载自:https://blog.csdn.net/u014595019/article/details/52554582 这个系列主要记录我在学习各个深度学习算法时候的笔记,因为之前已经学过大概 ...

  5. chrome中,BackstopJS 使用cookie文件后依旧提示需要登录

    1. 本地环境: apache-tomcat:7.05,jdk8, backstopJS:latest-version 配置tomcat管理用户成功:手工访问tomcat应用内部服务正常: 2.  问 ...

  6. Android 图形基础类Rect,扎实基础助腾飞

    转载请注明出处:王亟亟的大牛之路 上周把"垃圾桶动画写完了",然后这礼拜寻思着学习点啥,脑子闷逼了大半天,然后就找了点基础源码读读,把看的经历分享给大家. 先安利:https:// ...

  7. win10已计划自动重启怎么关

    此电脑->右击 管理->系统工具->任务计划程序->Microsoft->Windows->UpdateOrchestrator->Reboot 任务禁用

  8. dp_c_区间dp_g

    You Are The One 题意:有n个人准备按顺序上台,上台前有个小黑屋(先进后出,即栈),可以被安排进去等待,也可以直接上台,一个人一旦被安排进去,后面的人就可以先上台(小黑屋无限大).每个人 ...

  9. 2017 ACM/ICPC Asia 南宁区 L The Heaviest Non-decreasing Subsequence Problem

    2017-09-24 20:15:22 writer:pprp 题目链接:https://nanti.jisuanke.com/t/17319 题意:给你一串数,给你一个处理方法,确定出这串数的权值, ...

  10. JavaScript的动态特性(通过eval,call,apply和bind来体现)

    JavaScript的动态特性(通过eval,call,apply和bind来体现) JavaScript是一种基于面向对象的.函数式的.动态的编程语言.现在发展到已经可以用在浏览器和服务器端了. 这 ...