zoukankan      html  css  js  c++  java
  • Node进阶

      Node内存管理和垃圾回收

      

      node.js 是基于 V8 引擎的 javascript 运行环境。

      V8 引擎

      javascript 代码运行的时候提供编译优化、内存管理、垃圾回收等功能

      代码编译优化:

        1、通过 parser 将 javascript 源码转为 ast 抽象语法树

        2、将 ast 抽象语法树转为字节码,

        3、然后转为机器可运行的汇编代码

      内存管理:管理内存分配、内存划分

      垃圾回收:通过垃圾回收机制对无用代码释放内存

      内存管理

      类型

      常驻内存:运行 node 进程时候的所有内存( 代码占用内存、栈内存、堆内存、堆外内存 )

      栈内存:用于存放变量( javascript 中基本类型 )

      堆内存:用于存放对象、闭包引用上下文( 引用类型 )

      堆外内存:不是通过 V8 分配,不受V8管理,不占用V8内存。一些用于存放 buffer 数据的 ( buffer 对象依然在堆内存中 )

      

      限制

      默认给堆内存分配的大小:64位系统为 1.4G、32位系统为 0.7G

      可以通过 node 启动命令修改内存大小。

      不过分配的内存越大,垃圾回收一次的时间越长

      内存信息获取

      node 提供了 process.memoryUsage() 获取当前进程的内存信息

      rss :常驻内存大小( 进程分配的内存 )

      heapTotal:给 V8 分配的内存大小

      heapUsed:已使用的堆内存大小

      external:堆外使用的内存( buffer )

      1、内存溢出和堆外内存

    const fs = require('fs')
    
    const format = function (item, type = 0) {
        let ext = 'byte'
        switch (type) {
            case 1:
                ext = 'KB'
                break;
            case 2:
                ext = 'M'
                break;
            case 3:
                ext = 'G'
                break;
            case 3:
                ext = 'T'
                break;
        }
        if (item < 1024) return item.toFixed(2) + ext
        return format(item / 1024, type + 1)
    }
    
    function showMemory() {
        const memoryUsage = process.memoryUsage()
        console.log(`---------------------`)
        for (const item in memoryUsage) {
            console.log(`${item}:${format(memoryUsage[item])}`)
        }
    }
    
    showMemory()
    // 使用 40M 堆外内存
    const buffer = new ArrayBuffer(40 * 1024 * 1024)
    const total = []
    setInterval(() => {
        // 20M 内存的添加
        total.push(new Array(20 * 1024 * 1024))
        showMemory()
    },2000)
    

      

      垃圾回收

      释放一些在应用程序中不在被引用,或者空指针的一些变量的内存。

      1、变量为空的时候释放内存栈

      2、对象结束没引用或者引用的对象被清除的时候释放对应内存( 对象无法被根节点访问时候 )

      堆内存中的分类

      新生代:内存比较小,未经历垃圾回收的对象存放位置

        from 区:回收检查( 算法回收 ) 的时候,检查区

        to 区:回收检查( 算法回收 ) 的时候,from检查到对象被引用存活了

      老生代:内存是新生代20倍,from 区收检查( 算法回收 ) 的时候,已经经历过的对象或者to区满了时候送到老生代

      

      新生代垃圾回收

      新生代垃圾回收是通过交换 from 区和 to 区来实现的

      1、新建的对象被存放在 from 区,满了之后执行新生代垃圾回收检查

      2、检查 from 区对象,如果已经经历过一次检查且依然被引用的对象送到老生代区

      3、检查 from 区对象,如果被引用则总到 to 区,to 区满了25%则送到老生代区

      4、结束 from 检查后,交换 from 区和 to 区身份( from 区变 to区,反之 )

      5、再次检查,回到 1。

      老生代垃圾回收

      老生代垃圾回收没有新生代频繁

      主要通过判断是否被引用进行标记清除,然后对存活的对象整理

      1、检查老生代区,是否被引用,未被引用,释放该内存块的内存

      2、将依旧存活的对象,整理到老生代区的一端

      3、清除存活一端以外部分的内存块

      

      堆内存里面的对象主要是靠引用计数来判断是否释放内存(每引用一次增加1)

      内存泄漏场景

      

      1、未释放无用的全局变量/对象

      2、闭包的上下文

    function add() {
        const x = 1;
        const y = 2;
        return function (a) {
            return y + 2
        }
    }
    const add1 = add();
    /*
    * 执行 add() 后
    * x 将会被释放
    * y 将存在 add1 的上下文中,不会被释放( 除非 add1 = null )
    * */
    

      

      3、缓存大量数据

    // 分成小的一部分一部分处理
    const array = new Array(20 * 1024 * 1024)
    

      

      

      内存分析工具

      利用内存检查工具( node-heapdump、node-profiler ) 生成内存快照

      利用 chrome 进行分析。

  • 相关阅读:
    mapx 32位在win8 64位上使用
    ora01940 无法删除当前连接的用户
    powerdesigner操作
    iis7文件夹 首页设置
    安装vs2013以后,链接数据库总是报内存损坏,无法写入的错误
    【ASP.NET】 中 system.math 函数使用
    Android Bundle类
    android intent 跳转
    vs2012 webservice创建
    Linux中的日志分析及管理
  • 原文地址:https://www.cnblogs.com/jiebba/p/12767732.html
Copyright © 2011-2022 走看看