目录
- 内存治理为什么要监控??
- Performance 工具应用流程
-
内存问题
- 产生内存问题的景象及实质
- 界定内存问题的规范
-
监控内存的几种形式
- 浏览器工作管理器
- Timeline 时序图记录
-
堆快照查找拆散 DOM(能够察看内存泄露)
- DOM 存在的几种状态?
- 实例
- 怎么解决拆散 DOM?
-
判断是否存在频繁的垃圾回收(须要用不同的工具)
- 为什么要判断?
- 具体怎么用监控判断?
这里讲到的是应用 Performance
工具去进行监督内存和垃圾回收的状况,如果对内存治理,垃圾回收以及 GC
不太懂的请参考文章 JavaScript —— 内存治理及垃圾回收,上面开始进入正题
内存治理为什么要监控?
GC
的目标是为了实现内存空间的良性循环,良性循环的基石是 对内存空间正当应用 。因为HTML
中没有提供内存操作的 API
,所以时刻关注内存变动能力确定是否正当,咱们能够通过Performance
这个工具定位问题所在,Performance
工具提供多种监控形式,能够时刻监控内存。
Performance 工具应用流程
- 关上浏览器输出指标网址,这里用
Chrome
- 进入开发人员工具面板,抉择性能
Performance
- 开启录制性能,拜访具体界面
- 执行用户行为,一段时间后进行录制
- 取得报告,剖析界面中记录的内存信息
上面的截图,能够看到内存 Memory
的选项进去的折线图就示意了内存的时候状况,有升有降就是失常的工作:
内存问题
产生内存问题的景象及实质
限定以后网络问题失常的状况下:
呈现的景象 | 存在的问题 |
---|---|
页面呈现提早加载或者经常性暂停 | 内存有问题,与 GC 频繁的垃圾回收操作是有关联的,肯定存在代码中有让内存爆掉的状况 |
页面持续性呈现蹩脚的性能 | 存在内存收缩,以后界面为了达到最佳应用速度,会申请肯定的内存空间,这个内存空间大小超过了下限 |
页面的性能随工夫缩短越来越差 | 随同内存泄露 |
界定内存问题的规范
- 内存泄露:内存应用继续升高
- 内存收缩:以后应用程序自身为了达到最优成果须要肯定的内存空间,兴许与以后设施自身硬件不反对无关,所以产生了性能上的差别,须要去判断是程序的问题还是设施的问题。须要多做测试,在少数设施上都存在性能问题阐明程序自身有问题。
- 频繁垃圾回收:通过内存变动图进行剖析
监控内存的几种形式
浏览器工作管理器
以数值的模式将程序在执行的过程中内存的变动提现进去
在浏览器中 ->
shift+Esc
-> 右键选中【JavaScript
应用的内存】
- 第一列的内存是原生内存【
DOM
节点占据的内存】,这个数据增大示意创立了新的DOM
节点。 - 最初一列
JavaScript
内存是堆内存,界面中所有可达对象正在应用的内存大小。这个数据增大示意要么在创立新对象,要么对象在一直的增长。
上面进行一下实例:
<!-- 创立一个长度很大的数组 -->
<body>
<button id="add">Add</button>
<script>
const add = document.getElementById('add')
add.onclick = function() {let arrList = new Array(1000000)
}
</script>
</body>
点击按钮晓得内存会增大,是因为咱们创立了很大的数组。之后的脚本,能够拿这个去进行监控。
Timeline 时序图记录
下面的办法只能说咱们的内存存在问题,然而无奈更准确的定位什么工夫产生的,和那些代码有关系。咱们能够通过 Timeline
时序图间接把以后应用程序的走势以工夫点的形式出现进去。
上面进行一下实例:
<body>
<button id="btn">Add</button>
<script>
const arrList = []
function test() {for( let i = 0 ; i < 100000; i++) {document.body.appendChild(document.createElement('p'))
}
arrList.push(new Array(1000000).join('x'))
}
document.getElementById('btn').addEventListener('click',test)
</script>
</body>
进入页面,关上 performance
进行录制,点击三次按钮,进行录制。
能够看到内存是失常的,有升有降,降的中央就是 GC
在工作了。如果没有降的中央,就是有问题的中央。
堆快照查找拆散 DOM(能够察看内存泄露)
堆快照是很有针对性的查找以后的界面对象中是否存在一些拆散的 DOM
,拆散DOM
的存在也就是存在内存透露。
所以先搞清楚一下 什么是拆散 DOM?DOM 存在的几种状态?
DOM 存在的几种状态?
- 界面元素存活在
DOM
树上 - 垃圾对象时的
DOM
节点 ——DOM
从DOM
树上脱离了,js
外面也没有援用。 - 拆散状态的
DOM
节点 ——DOM
从DOM
树上脱离了,js
外面有援用,界面上看不见,存在内存外面。
实例
上面实例看一下,上面创立了 ul
和li
,这里没有在页面中出现,然而代码中有援用,这些就是拆散DOM
:
<!---->
<body>
<button id="btn">Add</button>
<script>
var tmpEle
function fn() {var ul = document.createElement('ul')
for (var i = 0; i < 10; i++) {var li = document.createElement('li')
ul.appendChild(li)
}
tmpEle = ul
}
document.getElementById('btn').addEventListener('click',fn)
</script>
</body>
关上浏览器 -> Memory
-> Profiles
-> Heap snapshot
-> Take snapshot
点击 Add
按钮 -> Take snapshot
-> 能够看到多进去的 ul
标签和 li
标签,这个就是拆散DOM
怎么解决拆散 DOM?
函数中把 temEle
置为 null
即可
var tmpEle
function fn() {var ul = document.createElement('ul')
for (var i = 0; i < 10; i++) {var li = document.createElement('li')
ul.appendChild(li)
}
tmpEle = ul
tmpEle = null
}
这个时候时候堆快照,拆散 DOM
就没有了。
判断是否存在频繁的垃圾回收(须要用不同的工具)
为什么要判断?
因为 GC
工作时应用程序是进行的,如果以后 GC
频繁工作,而且工夫过长的话对 Web
利用来说很不敌对,会导致利用假死说我状态,用户应用中会感知利用有卡顿。
具体怎么用监控判断?
- 通过 Timeline 时序图 判断,对以后性能面板中的内存走势进行监控,如果其中频繁的回升降落,就呈现了频繁的垃圾回收。这个时候要定位代码,看看是执行什么的时候造成了这种状况。
- 应用 浏览器工作管理器 会简略一些,工作管理器中次要是数值的变动,其数据频繁的霎时减少减小,也是频繁的垃圾回收。