内存
关注内存的原因:
- 防止页面占用内容过大,引起客户端卡顿,深圳无响应
- Node使用的是v8,由于服务器的持久性,后端很容易造成内存溢出
内存的大小
- 操作系统为64位的内存大小为1.4G,64位的新生代空间64MB,老生代为1400MB
- 操作系统为32位的为0.7G,32位的新生代空间16MB,老生代为700MB
为什么内存不扩大呢?
首先前端的特点是不持久化,执行一遍就全部回收,一般来说1.4G是足够的,其次JS在内存回收的时候会暂停执行,这将导致卡顿,内存越大,暂停越久。
新生代和老生代的含义及关系?
新生代简单理解就是复制,老生代就是标记删除整理。
新生代用来存储新产生的变量,老生代是新生代的变量符合一定的条件后才会放到老生代。(条件稍后再说)
小而新的变量先放在from空间内,进行一次回收,回收后还存活的变量放在to空间内,然后把from全部清空;再次发生回收时,进行from与to功能对调。
为什么要划分from和to?
这是牺牲空间来换去时间。
老生代,标记黑色的是需要删除的,回收后需要将内存整理成连续的,以便于使用。(例如数组必须要连续的内存空间)
新生代晋升到老生代需要满足的条件?
有两种方法:
- 经历过新生代两次次回收还存活的变量,可以放到老生代
- 占用内存过大,或者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进行释放。
内存优化技巧
- 尽量不要定义全局变量,定义后要及时销毁(赋值undefined或者null)
- 用匿名自执行函数
(function(){})()
- 尽量避免堆闭包的引用
防止内存泄漏
- 防止滥用内存
- 注意大内存的操作
缓存通常是在全局,因为要保证程序运行过程中活着,建议在进行V8缓存前加一道锁,也就是判断存储数据的数组长度,如果长度已经达到限制就将数据shift出去,按先进先出的方式删除之前的数据,push存储后来的数据。
大内存操作:例如文件处理
node小文件出咯可以使用fs.readFile()
node大文件处理可以使用createReadStream().pipe(write)
js可以使用切片上传的方式上传大文件(slice)
最后总结
学习V8引擎如何回收内存,需要了解V8引擎如何分配内存,了解变量处理,内存优化技巧,防止内存泄漏等。
以上内容是在某学习视频关于V8引擎内存回收讲解后的总结笔记