学习
实践
活动
工具
TVP
写文章
原创

内存控制

内存控制

v8垃圾回收机制与内存限制

内存问题

Node是 一个构建在Chrome的JavaScript运行时上的平台

内存控制正是在海量请求和长时间运行的前提下进行探讨的

在Node中通过JavaScript 使用内存时就会发现只能使用部分内存(无法操作大内存对象,例如读取2G的文件)

(64位系统下约为1.4 GB, 32位系统下约为0.7 GB)

V8限制内存的原因

开始是为浏览器设置的,不太可能会存在用到大量内存的场景

V8的垃圾回收机制限制,不控制内存会导致垃圾回收时间加长,阻塞 js 线程执行

这个限制可以通过 v8 提供的选项解除,如 node --max-old-space-size=1700 test.js

V8 的对象分配

在V8中,所有的JavaScript对象都是通过堆来进行分配的

根据对象的存货时间将内存的垃圾回收进行不同的分代,分别施以高效算法

老生代中的对象为存活时间较长或常驻内存的对象

新生代中的对象为存活时间较短的对象

V8 的垃圾回收机制

Scavenge算法:就是通过将存活对象在两个 semispace空间之间进行复制

典型的牺牲空间换取时间的算法,非常适合在生命周期短的新生代中应用

Mark-Sweep算法:通过标记活对象,清理死亡对象

Mark-Compact算法,将或对象移动到老生代一端,解决内存碎片问题

V8主要使用Mark-Sweep,在空间不足以对从新 生代中晋升过来的对象进行分配时才使用Mark-Compact。

垃圾回收需要将应用逻辑暂停下来即“全停顿”

垃圾回收的优化

· 拆分全停顿,应用执行一小会,垃圾回收执行一个拆分

· 延迟清理

· 增量式整理

高效使用内存

作用域

函数执行结束后,函数作用域被销毁,函数作用域中声明的变量也销毁

全局作用域需要直到 进程退出才能释放

如果需要释放常驻内 存的对象,可以通过delete操作来删除引用关系。或者将变量重新赋值,让旧的对象脱离引用关系。

V8中通过delete删除对象的属性有可能干扰V8 的优化, 所以通过赋值方式解除引用更好

闭包

作用域链上的对象访问只能向上,这样外部无法向内部访问

实现外部作用域访问内部作用域中变量的方法叫做闭包

即函数在定义的词法外部调用

闭包使得外部作用域对闭包定义的词法作用域有引用,因此词法作用域不会释放,内存也不会释放

在正常的JavaScript执行中,无法立即回收的内存有闭包和全局变量引用这两种情况

内存指标

进程的内存总共有几部分

rss 进程的常驻内存部分

交换区

文件系统

process.memoryUsage() 可以查看内存使用情况

堆中的内存用量总是小于进程的常驻内存用量,即内存并非都是通过V8分配的

不是通过V8分配的内 存称为堆外内存

os.totalmem() 可以查看系统的总内存

os.freemem() 可以查看系统的闲置内存

内存泄露

慎将内存当做缓存

在node 中一旦一个对象被缓存起来,就会被放到老生代中

长期存在的对象会使得垃圾回收扫描整理的时候对这些对象做无用功

由于模块的缓存机制,模块是常驻老生代的

采用进程外的缓存,进程自身不存储状态

关注队列外状态

一旦消费速度低于生产速度, 将会形成堆积

启用超时模式时,调用加入到队列中就 开始计时,超时就直接响应一个超时错误

拒绝模式时,当队列拥塞时,新到来的调用会直 接响应拥塞错误

内存泄露排查

node-heapdump

node-memwatch

通过对堆内存进行分析而找到

大内存应用

由于Node的内存限制,操作大文件 也需要小心,好在Node提供了stream模块用于处理大文件。

原创声明,本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

登录 后参与评论
0 条评论

相关文章

  • Nodejs·内存控制

    之前有考虑过Node中的内存管理,但是没想到Node的内存机制与JVM如此相像。 看完这部分的内容,基本可以了解Node中的内存使用技巧: 1 尽量不要做...

    用户1154259
  • 对象与内存控制

    JVM的垃圾回收机制是由一条后台线程执行的,其本身也是非常消耗内存的,因此,滥用创建对象,会导致性能大大下降,对内存的分配的了解就显得尤为重要

    迹_Jason
  • Node理论笔记:内存控制

    JavaScript和Java一样是由垃圾回收机制来进行自动内存管理的,对于浏览器,几乎不需要考虑内存回收的问题,但服务器对性能更为敏感,内存管理的好坏、垃圾回...

    Ashen
  • Linux 内存管理的水位控制

    在讲分区页框分配器分配内存的时候,进入伙伴算法前用函数zone_watermark_fast(),来根据水位来判断当前内存情况。内存够的话采用伙伴算法分配,不够...

    刘盼
  • 图解 Java 数组与内存控制

    Java的数组变量是一种引用类型的变量,数组变量并不是数组本身,它只是指向堆内存中的数组对象,改变一个数组变量所引用的数组,可以造成数组长度可变的假象。

    CoderJed
  • 详解 Java 对象与内存控制(下)

    以上程序说明:sub、mid和base这3个变量指向的Java对象拥有3个count实例变量,也就是说,需要3块内存来存储它们 当Sub sub = new ...

    CoderJed
  • 详解 Java 对象与内存控制(上)

    不管是类变量还是实例变量,你都不能引用一个还没有定义的变量,或者在引用之前没有定义的变量,如下图所示:

    CoderJed
  • Zynq:用PS控制DDR3内存读写

    本篇文章的目的主要用简明的方法对DDR3进行读写,当然这种方式每次读写都需要CPU干预,效率是比较低的,但是这是属于学习的过程,还是可以经历经历的。

    FPGA技术江湖
  • 028. RabbitMQ 持久化机制、内存磁盘控制

    山海散人
  • 第012课 内存控制器与SDRAM

    如图是S3C2440是个片上系统,有GPIO控制器(接有GPIO管脚),有串口控制器 (接有TXD RXD引脚)。

    韦东山
  • 《深入浅出Node.js》-内存控制

    本章学习 V8 的垃圾回收机制以及如何高效使用内存,内存泄漏以及如何排查内存泄漏。

    李振
  • 性能优化 | Go Ballast 让内存控制更加丝滑

    关于 Go GC 优化的手段你知道的有哪些?比较常见的是通过调整 GC 的步调,以调整 GC 的触发频率。

    haohongfan
  • 如何在 Go 中使用 CGroup 实现进程内存控制

    从 Linux 内核 2.6.25 开始,CGroup 支持对进程内存的隔离和限制,这也是 Docker 等容器技术的底层支撑。

    Laikee
  • 基于FPGA的内存128M flash芯片控制器设计

    大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。...

    FPGA技术江湖
  • 【翻译】linux中cgroups内存控制子系统memory.oom_control文件

    包含一个标志(0或1)来开启或者关闭cgroup的OOM killer。如果开启(1),任务如果尝试申请内存超过允许,就会被系统OOM killer终止。OOM...

    sean.liu
  • Oracle 12c基础教程:控制PDB中SGA 与 PGA 内存使用

    Oracle数据库资源管理器(资源管理器)现在可以在多租户容器数据库(CDB)中管理可插入数据库(PDBs)之间的内存使用。这一特性有助于在CDB中维护所有PD...

    星哥玩云
  • 内存溢出和内存泄露

    内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了...

    Demo_Yang
  • 内存篇:JVM内存结构

    Java8相对之前的版本,JVM结构发生了较大的变化,取消了永久代,新增了元空间,同时,元空间不再与堆连续,而且是存在于本地内存(Native memory)。...

    云深i不知处
  • golang 内存分析/内存泄漏

    进入交互式模式之后,比较常用的有 top、list、traces、web 等命令。

    用户5705150

扫码关注腾讯云开发者

领取腾讯云代金券