栈和堆

栈是连续的,用于存储普通变量(字符串、数字、布尔)
堆是一种无序的、散列的结构,用于存储对象。比如JavaScript使用new创建一个对象并将此对象赋值给一个变量。此对象实体被存在堆中,变量是指向对象实体储存地址的指针。

V8内存限制:

一般来说64位下是1.4G,32位下是700MB,但是根据浏览器不同,有些许扩容。Node情况下会有一些C++内存扩容。
使用 node --max-old-space-size=200或者node --max-old-space-size=200(单位为MB),来指定堆内存中老生代和新生代的最大值,是静态方法。运行时不能更改。
V8进行垃圾回收的时候是阻塞式的,也就是进行垃圾回收的时候会中断代码的执行。

新生代和老生代

新生代:

短时间存活的新变量会存在新生代中,新生代的内存量极少,64位下大概是32MB。
新生代的内存分为from空间(活动区域)和to空间(空白区域)。通过把from里面存活的变量复制到to空间。然后把from空间清空。然后对调from和to。这样可以提升回收速度,典型的牺牲空间换时间。

老生代:

生存时间比较长的变量,会转存到新生代,老生代占据了几乎所有内存。64位下大概是1400MB。
回收分为三步:

  1. 标记已死变量
  2. 清除已死变量
  3. 整理磁盘;为了节省磁盘空间

    新生代和老生代如何转化

  1. 新生代发现本次复制后,会占用超过25%的to空间。
  2. 这个对象已经经历过一次回收。

    什么时候触发回收

  3. 执行完一次代码。setTimeout的回调又会执行一次。

  4. 内存不够的时候。

    怎么判断一个变量可以回收

  5. 全局变量会直到程序执行完毕,才会回收。 ```javascript // node端 function memoryUsed() { const memory = process.memoryUsage().heapUsed; return memory/1024/1024 + ‘mb’ }

// windows端 window.performance.memory ```

  1. 普通变量,就是当他们失去引用。

    如何优化内存

  2. 尽量不要定义全局,或者定义了及时手动释放。

  3. 注意闭包。

    Node端一些特殊点

  4. Node可以手动触发垃圾回收。global.gc

  5. Node端可以设置内存