記一次性能優(yōu)化

有那么一句名言躲因,過早優(yōu)化是萬惡之源。指的就是在開發(fā)過程中,不用太早考慮性能問題大脉,而是要優(yōu)先實現(xiàn)功能和保持代碼清晰搁嗓,簡潔。更深的原因箱靴,是對個人的判斷的極端不信任腺逛。我們覺得重要的往往不重要,我們覺得不重要的事后才發(fā)現(xiàn)很重要衡怀。事前的判斷棍矛,往往會錯得離譜。所以抛杨,在軟件工程中够委,就放棄了事前對可能的性能占用情況的評估,而是在實現(xiàn)運行中怖现,通過軟件工具茁帽,來分析性能瓶頸,即:profiling.

我最近就遇到一個profiling的情況屈嗤。

最初是因為有那么一個bug潘拨。導(dǎo)致js后臺處理進程,一小時左右饶号,會自動退出铁追。經(jīng)過分析,我發(fā)現(xiàn)這是我所使用的kafka連接庫產(chǎn)生的問題茫船,這個問題不好修復(fù)琅束,但是我可以使用trick繞過它。處理之后算谈,進程不會報錯退出了涩禀,但是,在運行3-4小時后然眼,進程的處理性能會出現(xiàn)巨大的下降艾船,而且內(nèi)存占用會不停的增長,不停的刷新占用的上限罪治。

很明顯丽声,這個js進程存在內(nèi)存泄漏的情況礁蔗。

但是內(nèi)存泄漏是哪里產(chǎn)生的咧觉义?

由于之前沒有做過profiling,無法判斷是舊有的代碼就有問題,還是新加入的代碼導(dǎo)致的浴井。所以只能全局的去考慮晒骇。

最開始,我使用了nodejs自帶的profiling工具進行過一些cpu性能分析

https://nodejs.org/en/docs/guides/simple-profiling/

后來我又找到了更直觀的node-inspector

https://github.com/node-inspector/node-inspector

通過node-inspector分析,所能了解的也不多洪囤。只是看到closure徒坡,也就是閉包,有占到26%的內(nèi)存瘤缩,是最大的一項喇完。

這么說,是我代碼中的closure導(dǎo)致的內(nèi)存泄漏剥啤。我又搜索了相關(guān)資料锦溪,了解了一下closure導(dǎo)致內(nèi)存泄漏的常見形式。給我啟發(fā)最大的是這么一篇:

http://point.davidglasser.net/2013/06/27/surprising-javascript-memory-leak.html

在里面提到j(luò)s v8一個驚人的細節(jié)府怯。在同一作用域定義的閉包刻诊,會共享上下文(context),經(jīng)典的觸發(fā)代碼如下:

var str = new Array(1000000).join('*');

var doSomethingWithStr = function () {

? if (str === 'something')

? ? console.log("str was something");

? };

? doSomethingWithStr();

? var logIt = function () {

? ? console.log('interval');

? }

? setInterval(logIt, 100);

};

setInterval(run, 1000);

在這段代碼中l(wèi)ogIt和doSomethingWithStr共享上下文牺丙,引用了str则涯,導(dǎo)致str不被會gc清理,從而內(nèi)存泄漏冲簿。

我又看了一下代碼粟判,代碼中并沒有使用setInteval函數(shù),但使用的Rxjs峦剔,Rxjs的Observable.subscribe函數(shù)會不會有和setInteval函數(shù)類似的效果浮入。我立即寫了段代碼測試了一下。

var subscription = null

var sequence = null

function run() {

? var str = new Array(1000000).join('*');

? if (subscription != null) {

? ? subscription.dispose()

? }

var sequence = Rx.Observable.interval(200)

var subscription = sequence.subscribe(

? function() {

? ? console.log("str[0]=", str[0])

? })

}

setInterval(run, 500);

使用工具查看羊异,發(fā)現(xiàn)這段代碼會導(dǎo)致內(nèi)存占用迅速上升事秀,即存在內(nèi)存泄漏。

經(jīng)過試驗后野舶,我找到了初步的解決方案易迹。

var subscription = null

var sequence = null

function run() {

? var str = new Array(1000000).join('*');

? if (subscription != null) {

? ? subscription.dispose()

? }

? var sequence = Rx.Observable.interval(200).take(3)

? var subscription = sequence.subscribe(

? function() {

? ? console.log("str[0]=", str[0])

? } , function(err) {

? ? console.log("err=", err)

? } , function(err) {

? ? str=null

? ? console.log("completed")

? } )

}

setInterval(run, 500);

即在消息流結(jié)束的時候,將str對象置為null,來防止str對象的泄漏平道。本以為這就是最佳方案睹欲。無意中我又發(fā)現(xiàn),哪怕沒有在onCompleted函數(shù)一屋,只要流結(jié)束窘疮,也不會內(nèi)存泄漏。


我覺得這個rxjs的一個bug冀墨。在dispose后闸衫,不就是應(yīng)該該把要清理都清理了,是吧诽嘉?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蔚出,一起剝皮案震驚了整個濱河市弟翘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌骄酗,老刑警劉巖稀余,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異趋翻,居然都是意外死亡睛琳,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進店門踏烙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掸掏,“玉大人,你說我怎么就攤上這事宙帝∩シ铮” “怎么了?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵步脓,是天一觀的道長愿待。 經(jīng)常有香客問我,道長靴患,這世上最難降的妖魔是什么仍侥? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮鸳君,結(jié)果婚禮上农渊,老公的妹妹穿的比我還像新娘。我一直安慰自己或颊,他們只是感情好砸紊,可當我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著囱挑,像睡著了一般醉顽。 火紅的嫁衣襯著肌膚如雪炬转。 梳的紋絲不亂的頭發(fā)上蹬昌,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天,我揣著相機與錄音秉馏,去河邊找鬼通熄。 笑死唆涝,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的唇辨。 我是一名探鬼主播廊酣,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼助泽!你這毒婦竟也來了啰扛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤嗡贺,失蹤者是張志新(化名)和其女友劉穎隐解,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诫睬,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡煞茫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了摄凡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片续徽。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖亲澡,靈堂內(nèi)的尸體忽然破棺而出钦扭,到底是詐尸還是另有隱情,我是刑警寧澤床绪,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布客情,位于F島的核電站,受9級特大地震影響癞己,放射性物質(zhì)發(fā)生泄漏膀斋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一痹雅、第九天 我趴在偏房一處隱蔽的房頂上張望仰担。 院中可真熱鬧,春花似錦绩社、人聲如沸摔蓝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽项鬼。三九已至,卻和暖如春劲阎,著一層夾襖步出監(jiān)牢的瞬間绘盟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工悯仙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留龄毡,地道東北人。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓锡垄,卻偏偏與公主長得像沦零,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子货岭,可洞房花燭夜當晚...
    茶點故事閱讀 43,492評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 工廠模式類似于現(xiàn)實生活中的工廠可以產(chǎn)生大量相似的商品路操,去做同樣的事情疾渴,實現(xiàn)同樣的效果;這時候需要使用工廠模式。簡單...
    舟漁行舟閱讀 7,724評論 2 17
  • 單例模式 適用場景:可能會在場景中使用到對象屯仗,但只有一個實例搞坝,加載時并不主動創(chuàng)建,需要時才創(chuàng)建 最常見的單例模式魁袜,...
    Obeing閱讀 2,058評論 1 10
  • 函數(shù)聲明和函數(shù)表達式有什么區(qū)別 (*)解析器會率先讀取函數(shù)聲明桩撮,并使其在執(zhí)行任何代碼之前可以訪問;函數(shù)表達式則必須...
    coolheadedY閱讀 385評論 0 1
  • 一峰弹、數(shù)組 數(shù)組是一個有序列表,所以有下標. 并且數(shù)組在js中可以存在任意類型的數(shù)據(jù).并且同一個數(shù)組中可以存放不同的...
    空谷悠閱讀 506評論 0 1
  • 相關(guān)知識點 數(shù)據(jù)類型店量、運算、對象鞠呈、function融师、繼承、閉包蚁吝、作用域诬滩、原型鏈、事件灭将、RegExp疼鸟、JSON、Aj...
    sandisen閱讀 11,373評論 7 175