深刻浅出Node(5) 内存控制

一)V8垃圾回收机制javascript

  1.1 V8的内存限制java

  1.2 V8垃圾回收机制  node

二) 高效使用内存算法

  2.1 内存空间的释放数组

  2.2 使用堆外内存浏览器

  2.3 合理使用内存防止内存泄漏缓存

    2.3.1 慎将内存当缓存服务器

    2.3.2 关注队列状态闭包

  2.3 大内存应用函数

一)V8垃圾回收机制

  Node使用的是Chrome的V8引擎执行javascript,因为运行在浏览器和服务端的场景不一样,浏览器中网页的运行时间较短,随着网页的关闭,相应的内存就会被回收,因此对精细的内存的管理需求度不高,可是在服务器端因为程序处于长时间运行中,为了达到高性能的服务端程序,就须要良好的垃圾回收策略和管理策略(机器和咱们自己的控制) 良好的管理策略能更好的使垃圾回收运行,垃圾回收是影响性能的因素之一

  V8的内存限制

  因为V8在内存回收算法的使用的考虑下,V8给系统分配使用的内存是存在必定的限制的

  V8垃圾回收机制

  在垃圾回收机制上,V8主要根据内存中对象在内存中的特征,对内存中的对象进行分区的管理.如下为V8的堆内存的划分

在新生区的内存空间中,因为新生区内存对象的特征是生存周期短,这部分采用Cheney算法.Cheney算法是一种采用复制方式实现的垃圾回收算法,它将新生代内存空分为两个区域:

处于使用状态的From区域和处于闲置状态的To区域.在分配对象的时候,会如今From区域中进行对象的分配,在进行垃圾回收的时候,将From区域中存活的对象copy到To区域而且将From区域和To区域进行角色互换.

当一个对象在进行屡次复制仍然存活,它就会被认为是存活周期较长的对象,它就会被转移到老生区域中.对象重新生区域移动到老生区域的过程称为晋升. 晋升主要有两个条件:

  1. 一个对象时候经历过Scavenge回收(也就是新生区域的垃圾回收)
  2. To空间的内存占比(当To区域已经使用了25%的时候,从From区域复制的对象会直接晋升到老生区域.由于To区域会在接下来转换为From区域供新的内存的分配,须要预留合适大小的空间)

在老生区域主要采用Mark-sweep 和Mark-Compact 和 Incremental Marking等多种方式结合的方式来达到对老生区进行整理的目的

  • Mark-sweep 标记清除 主要分为标记和清除 在标记阶段,垃圾回收器会标记活着的对象,在清除阶段会清除没有被标记的对象
  • Mark-Compact 标记整理  它是在标记清除的基础上的,在进行标记的过程当中,将活着的对象往一侧进行移动,这样就消除了内存的间隙,方便后续内存空间的分配
  • Incremental Marking 增量标记 在进行标记的时候,须要将应用程序的逻辑进行暂停,因此产生了增量标记,每次只标志部分,在让位出时间来执行应用程序.

 二)高效使用内存

  2.1 内存空间的释放

  变量是引用的状况下须要主动的释放内存,例如对引用进行从新的赋值,这样在垃圾回收器运行的时候,就会主要回收内存. 

  闭包是外部做用域访问内部做用域中变量的方法,在使用完闭包后,要注意中间函数的释放

  2.2 使用堆外内存

  Buffer对象的内存分配不通过V8的内存分配机制,因此在处理文件I/O的时候可使用Buffer来达到对堆外内存的使用

  2.3 合理使用内存防止内存泄漏

  形成内存泄漏的缘由是咱们的操做使得本应在垃圾回收中被回收的内存没法被回收,变成老生区对象.主要有如下几个缘由

  • 缓存
  • 队列消费不及时
  • 做用域未释放

2.3.1 慎将内存当缓存

  当咱们将一个对象常驻内存中做为缓存使用的时候(老生区),垃圾回收算法每次都会对它进行操做,这就致使垃圾回收在作无用功而且咱们对这个缓存对象的大小不作控制的时候,还可能会致使它占用过大的内存空间,致使进程的退出,而且内存做为缓存这种方案没法再各个进程间进行共享,解决方案是使用缓存软件,他们拥有良好的管理策略,能更好的提高应用的性能.

2.3.2 关注队列状态

  在使用队列(数组)来完成特殊的任务请求的时候,当任务的消耗低于生产的时候,就会形成堆积,产生内存泄漏.解决方案是设置警告或者超时响应等

  2.4 大内存应用

  对于大内存应用,例如读取大的文件,可使用node中的stream模块而且它继承了event模块.

相关文章
相关标签/搜索