? ? ? ? 額,這兩天主要是圍繞著上海的項(xiàng)目按照客戶的需求更改設(shè)計(jì),在這個(gè)過(guò)程中,有一個(gè)隱藏特別深的bug在項(xiàng)目中暴露出來(lái),在測(cè)試環(huán)境中沒(méi)有暴露,而且很難復(fù)現(xiàn),其實(shí)現(xiàn)在想想自己挺蠢的,一個(gè)簡(jiǎn)單的問(wèn)題折騰了一個(gè)下午才解決也是沒(méi)誰(shuí)了,現(xiàn)在特地寫(xiě)出來(lái)長(zhǎng)個(gè)教訓(xùn),希望看到這篇簡(jiǎn)書(shū)的朋友們也不要犯我這個(gè)低級(jí)錯(cuò)誤,下面我將展開(kāi)復(fù)盤(pán)一下這個(gè)問(wèn)題的始末:??
? ? ? ?1項(xiàng)目描述:本公司和上海某個(gè)公司合作,我們公司的項(xiàng)目部署在上海的某個(gè)服務(wù)器上進(jìn)行現(xiàn)場(chǎng)大屏展示給某些領(lǐng)導(dǎo),并且進(jìn)行功能演示,出于保密原因,照片不做展示,可以看出,頁(yè)面呈現(xiàn)崩潰狀態(tài),其他組件頁(yè)面也有類(lèi)似的情況發(fā)生,時(shí)間段不一定分布在一個(gè)小時(shí)左右,看到一線人反饋的問(wèn)題,當(dāng)時(shí)心都涼了。
? ? ? ?2 問(wèn)題定位:這個(gè)問(wèn)題在測(cè)試環(huán)境下沒(méi)有測(cè)試到,壓力測(cè)試也沒(méi)有測(cè)試,而且打開(kāi)控制臺(tái),發(fā)現(xiàn)并沒(méi)有error;可以看出這個(gè)問(wèn)題并不能很好的復(fù)現(xiàn)。筆者看到這個(gè)問(wèn)題的下意識(shí)是內(nèi)存溢出,但是這個(gè)內(nèi)存溢出可能是java后臺(tái)的可能性比較大 ,因?yàn)閖s本身并不涉及到性能問(wèn)題,于是和后臺(tái)一起進(jìn)行性能測(cè)試,后臺(tái)反饋,java后臺(tái)內(nèi)存并沒(méi)有溢出:截圖如下:
如果不是后端的原因,只能是前端的原因了。在這里要說(shuō)一下,首頁(yè)的狀態(tài)是每隔兩分鐘就要向后臺(tái)發(fā)起請(qǐng)求更新前臺(tái)數(shù)據(jù),筆者的潛意識(shí)里應(yīng)該是上一次數(shù)據(jù)沒(méi)有及時(shí)銷(xiāo)毀,導(dǎo)致內(nèi)存占用過(guò)多,于是將更新時(shí)間縮短,進(jìn)行100毫秒刷新,觀察控制臺(tái)的情況:
大約過(guò)了過(guò)4分鐘左右,頁(yè)面出現(xiàn)崩潰狀態(tài),筆者趕緊打開(kāi)控制臺(tái),發(fā)現(xiàn)如下問(wèn)題:
可以確定是我的問(wèn)題了,但是具體問(wèn)題出現(xiàn)在哪里仍然不是很清楚,于是借助谷歌瀏覽器工具進(jìn)行debug,截圖和提示如下:
通過(guò)上面這個(gè)圖可以肯定就是我的定時(shí)器有問(wèn)題,但是定時(shí)器的問(wèn)題到底出現(xiàn)在哪里,繼續(xù)根據(jù)memory進(jìn)行定位:
到這里問(wèn)題的原因就就已經(jīng)確定了,可以看出有Object造成的影響排在了第二位,因?yàn)閷?duì)象本身會(huì)關(guān)聯(lián)很多數(shù)組,字符串以及其他內(nèi)容,問(wèn)題確定,這個(gè)定時(shí)器產(chǎn)生了好多對(duì)象,于是檢查代碼:
上圖中的echart對(duì)象如下:?
到現(xiàn)在,問(wèn)題的根本原因已經(jīng)找到了,就是在定時(shí)器里面不斷的構(gòu)造echart對(duì)象,這個(gè)echart對(duì)象會(huì)在vue實(shí)例上不斷的增加,導(dǎo)致舊的對(duì)象沒(méi)有銷(xiāo)毀,新的對(duì)象不斷產(chǎn)生,每生成一個(gè)新的對(duì)象就會(huì)申請(qǐng)占用一塊內(nèi)存,短時(shí)間內(nèi)不會(huì)爆發(fā),但是一旦達(dá)到這個(gè)瀏覽器承受的閾值,內(nèi)存泄露,導(dǎo)致頁(yè)面崩潰。
此時(shí)此刻,心理就是自己真蠢。
? ? ? 3問(wèn)題解決:筆者之所以每次不斷的new對(duì)象是因?yàn)槊看涡聛?lái)的數(shù)據(jù)都要通過(guò)這個(gè)函數(shù)的參數(shù)傳入進(jìn)去,試圖在外面new一個(gè)對(duì)象在定時(shí)器里面跟新vue的data數(shù)據(jù)是有錯(cuò)誤的,這個(gè)本人親自試過(guò),那么既然這種辦法行不通了,只能在傳入數(shù)據(jù)前進(jìn)行對(duì)象判斷了,但是老對(duì)象和新對(duì)象看似一樣,其實(shí)他是兩個(gè)不同的個(gè)體,證據(jù)如下:
于是打印這個(gè)echrt對(duì)象,發(fā)現(xiàn)每個(gè)對(duì)象多出一個(gè)ID,我們可以通過(guò)判斷ID的方法來(lái)修復(fù)這個(gè)問(wèn)題,
到現(xiàn)在進(jìn)過(guò)5個(gè)小時(shí)的定位和分析,問(wèn)題解決了,但是還沒(méi)有根治,我們只是通過(guò)一個(gè)函數(shù)阻止了重造行為,真正的做法應(yīng)該是定時(shí)器里面就他不應(yīng)該重造,在定位的過(guò)程中,后臺(tái)指出了我代碼中的不足之處,非常感謝,只有不斷的review才能進(jìn)步,在這里特別感謝他們。
參考鏈接如下面:阮一峰內(nèi)存泄露教程? ? ? ? ? ? ? ? ? ?performance學(xué)習(xí)方法? ? ? ? ? Memory學(xué)習(xí)方法? ? ? ? ? ? ? ? ? ?一個(gè)Vue頁(yè)面的內(nèi)存泄露分析??