V8引擎如何回收内存以及如何优化

内存

关注内存的原因:

  • 防止页面占用内容过大,引起客户端卡顿,深圳无响应
  • Node使用的是v8,由于服务器的持久性,后端很容易造成内存溢出

内存的大小

  • 操作系统为64位的内存大小为1.4G,64位的新生代空间64MB,老生代为1400MB
  • 操作系统为32位的为0.7G,32位的新生代空间16MB,老生代为700MB
    在这里插入图片描述
    为什么内存不扩大呢?
    首先前端的特点是不持久化,执行一遍就全部回收,一般来说1.4G是足够的,其次JS在内存回收的时候会暂停执行,这将导致卡顿,内存越大,暂停越久。

新生代和老生代的含义及关系?

新生代简单理解就是复制,老生代就是标记删除整理。

新生代用来存储新产生的变量,老生代是新生代的变量符合一定的条件后才会放到老生代。(条件稍后再说)

小而新的变量先放在from空间内,进行一次回收,回收后还存活的变量放在to空间内,然后把from全部清空;再次发生回收时,进行from与to功能对调。

为什么要划分from和to?
这是牺牲空间来换去时间。

老生代,标记黑色的是需要删除的,回收后需要将内存整理成连续的,以便于使用。(例如数组必须要连续的内存空间)
在这里插入图片描述新生代晋升到老生代需要满足的条件?

有两种方法:

  1. 经历过新生代两次次回收还存活的变量,可以放到老生代
  2. 占用内存过大,或者To的空间已经使用了25%(64位系统即8MB),此时会直接进入老生代。
    在这里插入图片描述

如何查看内存情况

方式一:
在浏览器控制台输入window.performance或者总结使用Memory
浏览器:
在这里插入图片描述或者
在这里插入图片描述方式二:
Node环境下可以通过process.messoryUsage()查看内存情况
在这里插入图片描述

external是额外的内存,是C++的内存,由于node是C++写的,有分配C++内存的权力,所以可以进行扩容,但是只能在Node环境下。

方式三:通过js代码实现

function getMe() {
    var men = process.memoryUsage()
    return men
}
console.log(getMe())

转换成MB格式更为直观

function getMe() {
    var men = process.memoryUsage();
    var format = function(bytes){
        return (bytes/1024/1024).toFixed(2)+"MB"
    }
    console.log(format(men.heapTotal))
}
getMe() 

变量处理

内存主要就是存储变量等数据的
局部变量当程序执行结束,且没有引用的时候就可以被清理,但是不是立即回收,需要等待。
全局对象会始终运行到程序运行结束,可以通过给全局变量赋值undefined或者null进行释放。

内存优化技巧

  1. 尽量不要定义全局变量,定义后要及时销毁(赋值undefined或者null)
  2. 用匿名自执行函数(function(){})()
  3. 尽量避免堆闭包的引用

防止内存泄漏

  1. 防止滥用内存
  2. 注意大内存的操作

缓存通常是在全局,因为要保证程序运行过程中活着,建议在进行V8缓存前加一道锁,也就是判断存储数据的数组长度,如果长度已经达到限制就将数据shift出去,按先进先出的方式删除之前的数据,push存储后来的数据。

大内存操作:例如文件处理
node小文件出咯可以使用fs.readFile()
node大文件处理可以使用createReadStream().pipe(write)
js可以使用切片上传的方式上传大文件(slice)

最后总结

学习V8引擎如何回收内存,需要了解V8引擎如何分配内存,了解变量处理,内存优化技巧,防止内存泄漏等。

在这里插入图片描述

以上内容是在某学习视频关于V8引擎内存回收讲解后的总结笔记

发布了128 篇原创文章 · 获赞 52 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_44523860/article/details/105351255