创新互联长期为近1000家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为官渡企业提供专业的成都网站建设、网站制作,官渡网站改版等技术服务。拥有十多年丰富建站经验和众多成功案例,为您定制开发。
如果页面卡顿、或者半夜内存飙升,你觉得可能是什么原因造成的?有什么办法锁定原因并解决吗?(项目常用)
这是一个非常宽泛而又有深度的问题,涉及到很多的页面性能优化问题,我依稀还记得当初面试被问到这个问题时是这么回答的:
1)先会检查是否是网络请求太多,导致数据返回较慢,可以适当做一些缓存;
2)也有可能是某块资源的bundle太大,可以考虑拆分一下;3)然后排查一下js代码,是不是某处有过多循环导致占用主线程时间过长;
4)浏览器某帧渲染的东西太多,导致的卡顿;
5)在页面渲染过程中,可能有很多重复的重排重绘;
后来了解到了,感官上的长时间运行页面卡顿也有可能是因为内存泄漏,内存溢出引起的。
1、内存溢出
1)一种程序运行出现的错误。
2)当程序运行所需内存超过了计算机剩余的内存时,程序崩溃并抛出内存溢出的错误。
例如:系统已经不能再分配出你所需要的空间,比如你需要100M的空间,系统只剩90M了,这就叫内存溢出。
2、内存泄漏
1)指内存被占用且没有及时释放。
2)内存泄漏越多,计算机剩余的内存就越小,此时越容易发生内存溢出。
常见的内存泄露情况:
1)意外的全局变量
2)未及时清理计时器或回调函数
3)闭包
例如:用资源的时候为他开辟了一段空间,当你用完时忘记释放资源了,这时内存还被占用着,一次没关系,但是内存泄漏次数多了就会导致内存溢出。内存泄漏是导致迟缓,崩溃的根本原因,甚至会导致其他应用问题。
垃圾回收机制(GC)
根据内存泄漏的定义,有些变量或数据不再被使用或不需要了,那么它就是垃圾变量或垃圾数据,如果其一直保存在内存中,最终可能会导致内存占用过多的情况。那么此时就需要对这些垃圾数据进行回收,这里引入了垃圾回收机制的概念。
1、GC定义与作用
GC 就是垃圾回收机制的简写;
GC 可以找到内存中的垃圾、并释放和回收空间;
2、GC里的垃圾是什么
1) 程序中不再需要使用对象
- function func() {
- name = 'lg'
- return `${name} is a coder`
- }
- func()
2) 程序中不再需要使用对象
- function func() {
- const name = 'lg'
- return `${name} is a coder`
- }
- func()
3、常见 GC 算法- 引用计数
引用计数算法实现原理
引用计数算法(重要)
- const user1 = {age: 11}
- const user2 = {age: 22}
- const user3 = {age: 33}
- const nameList = [user1.age, user2.age, user3.age]
- function fn() {
- const num1 = 1;
- const num2 = 2;
- }
- fn();
说明:fn() 的num1,num2会被回收。
4、常见 GC 算法- 标记清除
标记清除算法实现原理
- function speakLines(){
- let night="天黑";//做个标记 ,进入环境
- let closeEyes="闭眼";//做个标记 ,进入环境
- let speak=`开始狼人杀,${night}请${closeEyes}`;//做个标记 ,进入环境
- console.log(speak);
- }
- speakLines() //代码执行完毕 里面被标记过的变量,又被标记 离开环境 最后被回收
用户反馈的说是半夜没人用的时候内存飙升了,node内存的溢出的问题分析。
1、先期排查(重要)
先期排查的内容,信息如下:
1) 日志:数据分析大小,内存溢出日志。
2) 监控:开启Sentry监控,Sonar代码质量,阿里云监控。
1) 报错日志
a. 数据分析
b. 报错日志
- 2021-05-13 22:26:48:198S: FATAL ERROR:
- CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
- 2021-05-15 00:18:33:670S: FATAL ERROR:
- Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
2、问题分析 (重要)
1) V8引擎对Node.js(和Chrome V8)中的内存限制大小。
2) 代码分析:内存泄漏出现情况(重要)
3、Nodejs内存 - 扩大容量
V8引擎对Node.js(和Chrome V8)中的内存限制大小。
原因
因为在Node中,通过JavaScript使用内存时只能使用部分内存(64位系统:1.4 GB,32位系统:0.7 GB),这个时候,如果前端项目非常的庞大,Webpack编译时就会占用很多的系统资源,如果超出了V8引擎对Node默认的内存限制大小时,就会产生内存溢出的错误。
- "scripts": {
- "dev": "node build/dev-server.js",
- "start": "node build/dev-server.js",
- "build": "set NODE_ENV=production && node --max_old_space_size=4096 build/build.js",
- "e2e": "node test/e2e/runner.js",
- "test": "npm run e2e"
- },
第一步:在packagejson里添加这两个插件
- npm install -g increase-memory-limit
- npm install cross-env
第二步:在package.json里的scripts里进行配置
- "scripts": {
- "fix-memory-limit": "cross-env LIMIT=8192 increase-memory-limit"
- },
LIMIT是你想分配的内存大小,这里的8192单位是M也就是8G(具体的大小根据实际情况而定);
第三步:
- npm run fix-memory-limit
*说明:增加内存限制大小,并不能够实质解决问题。
扩展知识
1、认识 V8
因为在Node中,通过JavaScript使用内存时只能使用部分内存(64位系统:1.4 GB,32位系统:0.7 GB)
2、V8 垃圾回收策略
3、V8 如何回收新生代对象
V8 内存分配
新生代对象回收实现
回收细节说明
4、V8 如何回收老生代对象
老年代对象说明
老年代对象回收实现
细节对比
标记增量如何优化垃圾回收
监控内存的几种方式(重要)
chrome内存泄露、内存泄漏分析工具
内存分析使用的工具包括chrome任务管理器、chrome时间轴(低版本是Timeline,高版本对应performance)、chrome memory(低版本是chrome profiles,主要用JS堆快照、JS堆动态分配时间轴)。
1) 使用Chrome任务管理器,了解网页使用的内存量。
2) 使用时间轴记录可视化内存使用。
3) 使用堆快照标识分离的DOM树(内存泄漏的常见原因)。
4) 通过堆动态分配时间轴记录了解在JS堆中分配及回收情况。
首先打开Chrome的无痕模式,这样做的目的是为了屏蔽掉Chrome插件对我们之后测试内存占用情况的影响。
然后打开开发者工具,找到Performance这一栏,可以看到其内部带着一些功能按钮,例如:开始录制按钮;刷新页面按钮;清空记录按钮;记录并可视化js内存、节点、事件监听器按钮;触发垃圾回收机制按钮等等。
简单录制一下百度页面,看看我们能获得什么,如下动图所示:
从上图中我们可以看到,在页面从零到加载完成这个过程中JS Heap(js堆内存)、documents(文档)、Nodes(DOM节点)、Listeners(监听器)、GPU memory(GPU内存)的最低值、最高值以及随时间的走势曲线,这也是我们主要关注的点。再来看看开发者工具中的Memory一栏,其主要是用于记录页面堆内存的具体情况以及js堆内存随加载时间线动态的分配情况
代码优化介绍(重要)
递归导致内存溢出 (函数执行中再次调用自己执行)
- // 下面案例是“死递归” Uncaught RangeError: Maximum call stack size exceeded “内存溢出”
- function fn(x) {
- // console.log(x);
- fn(x + 1);
- }
- fn(1);
虽然JavaScript会自动垃圾收集,但是如果我们的代码没有及时清空一些被调用的东西,就会让变量一直处于无法回收状态。
全局变量引起
- function leaks(){
- leak = 'xxxxxx';//leak 成为一个全局变量,不会被回收
- }
闭包
- var leaks = (function(){
- var leak = 'xxxxxx';// 被闭包所引用,不会被回收
- return function(){
- console.log(leak);
- }
- })()
被遗忘的计时器
- var someResource = getData();
- setInterval(function() {
- var node = document.getElementById('Node');
- if(node) {
- // Do stuff with node and someResource.
- node.innerHTML = JSON.stringify(someResource));
- }
- }, 1000);
eval 使用
使用eval()函数会带来安全隐患,eval()函数的作用是返回任意字符串,当作js代码来处理。
原来代码:
- this.formColor = eval('(' + resp.responsePageData.sysColor + ')');
处理后代码:
- this.formColor = JSON.parse(resp.responsePageData.sysColor);
在项目过程中,如果遇到了某些性能问题可能跟内存泄漏有关时,就可以参照本文方法去排查,一定能找到问题所在并给到解决办法的。
虽然JavaScript的垃圾回收是自动的,但我们有时也是需要考虑要不要手动清除某些变量的内存占用的,例如你明确某个变量在一定条件下再也不需要,但是还会被外部变量引用导致内存无法得到释放时,你可以用null对该变量重新赋值就可以在后续垃圾回收阶段释放该变量的内存了。
当前标题:内存溢出分析及解决实践
分享URL:http://www.shufengxianlan.com/qtweb/news44/254544.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联