久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

內(nèi)存

 蹇勝雄 2016-09-18

JS里有兩個(gè)常見(jiàn)的難點(diǎn),其一是原型繼承,,其二是閉包,前者涉及原型鏈而后者涉及作用域鏈(Scope Chain)

function對(duì)象保存了閉包中的信息,,這個(gè)說(shuō)法是不確切的,應(yīng)該說(shuō),,function形成的scope chain阻止了閉包中變量被釋放,,從而使它再次被執(zhí)行時(shí)仍能保留上下文

我們打開(kāi)一個(gè)干凈無(wú)插件的Chrome,,訪(fǎng)問(wèn)about:blank,打開(kāi)F12開(kāi)Profile當(dāng)中的Record Heap Allocation功能(記錄內(nèi)存分配,?),,然后把題主的代碼稍微改得更消耗內(nèi)存一些,改成定時(shí)爆炸方便我們抓情況

var fn;
setTimeout(function(){
    var a = new Array(1000).join('long text');
    fn = function () {
        console.log(a);
    };
}, 3000);

回車(chē)執(zhí)行代碼,,3秒內(nèi)點(diǎn)record,,等函數(shù)執(zhí)行會(huì)看到分配了若干內(nèi)存,停止錄制(大圓點(diǎn)),,在窗口中可以看到被分配的各種對(duì)象,,我們看看那個(gè)很長(zhǎng)的字符串,在string類(lèi)型里面一下子就能找到

正好我們也看見(jiàn)了另一個(gè)沒(méi)有名字的字符串,,看看兩者的區(qū)別

區(qū)別很明顯,,retaining tree 相當(dāng)于對(duì)象和window object聯(lián)系的路徑,在GC時(shí),,瀏覽器會(huì)試圖尋找內(nèi)存中retaining tree為空,,或者說(shuō)引用計(jì)數(shù)為零的對(duì)象予以回收。JS的特殊之處就在于,,除了顯示的對(duì)象屬性(fn in Window)之外,,函數(shù)對(duì)象對(duì)其閉包所有的變量也都算作引用計(jì)數(shù)(context in function)

換句話(huà)說(shuō),不是函數(shù)對(duì)象在保存了上下文的數(shù)據(jù),,而是函數(shù)對(duì)象保持了對(duì)上下文的引用,阻止GC回收上下文中的數(shù)據(jù),。


至于函數(shù)體在內(nèi)存中的形式,,就是一個(gè)更復(fù)雜的話(huà)題了,之前看得那篇文章找不到了我簡(jiǎn)單說(shuō)說(shuō)我記得的東西吧,,現(xiàn)代JS引擎都是JIT實(shí)時(shí)優(yōu)化的,,首先函數(shù)剛被創(chuàng)建的時(shí)候,經(jīng)過(guò)詞法分析等步驟形成了最開(kāi)始能跑的第一份函數(shù)體,,由于JS的特性,,其二進(jìn)制代碼中會(huì)有非常多的類(lèi)型探測(cè)、判斷等邏輯,,執(zhí)行效率非常低,,然后函數(shù)被執(zhí)行時(shí),除了拿函數(shù)體出來(lái)執(zhí)行之外,,JS引擎會(huì)首先會(huì)記錄下這個(gè)函數(shù)被執(zhí)行了,,其次還會(huì)跟蹤其輸入?yún)?shù)的類(lèi)型,函數(shù)每被執(zhí)行一定次數(shù),,JS引擎就會(huì)嘗試優(yōu)化一次函數(shù)體,,根據(jù)之前記錄的各種信息來(lái)進(jìn)行優(yōu)化,,也就是說(shuō)執(zhí)行次數(shù)越多,,參數(shù)類(lèi)型越一致,,那么函數(shù)體在內(nèi)存中的優(yōu)化程度就越高,,甚至最后可以逼近C的性能。

打比方的話(huà)JS代碼

function my(obj) { return obj.toString(); }

最開(kāi)始可能內(nèi)存里長(zhǎng)這樣

name: my
source: ...(源代碼)
body:
    return get(obj, toString).call obj
get:
    if hasOwn(obj, toString)
        return obj{toString}
    else
        proto = obj{__proto__}
        while proto is not null && !hasOwn(proto, toString)
            proto = proto{__proto__}
        if !hasOwn(proto, toString)
            throw object has no toString
        return proto{toString}

然后my(3) 1000次以后可能就變成了

name: my
source: ...(源代碼)
body:
    if(obj is simple number)
        return body_number()
    else 
        return body_slow()
numberToString: Number.prototype.toString
body_number:
    return numberToString.call obj
body_slow:
    return get(obj, toString).call obj
get:
    if hasOwn(obj, toString)
        return obj{toString}
    else
        proto = obj{__proto__}
        while proto is not null && !hasOwn(proto, toString)
            proto = proto{__proto__}
        if !hasOwn(proto, toString)
            throw object has no toString
        return proto{toString}

總之就是運(yùn)行次數(shù)越多,,函數(shù)體在內(nèi)存中被優(yōu)化得越激進(jìn)


把之前看的那片文章翻了出來(lái) http://djt.qq.com/article/view/489 QQ瀏覽器的開(kāi)發(fā)寫(xiě)的
關(guān)于字節(jié)碼的部分隨便看看就好,,V8已經(jīng)不產(chǎn)生字節(jié)碼了,,隨著V8的開(kāi)源,別家引擎遲早會(huì)跟進(jìn),。
我主要想說(shuō)的就是JIT熱點(diǎn)跟蹤那部分,,也就是『運(yùn)行次數(shù)越多,,函數(shù)體就會(huì)被越激進(jìn)地優(yōu)化』,,至于例子里的類(lèi)型推斷優(yōu)化,,只是判斷為熱點(diǎn)后優(yōu)化的一種而已,,實(shí)際上優(yōu)化的手段會(huì)有很多,展開(kāi)循環(huán)/循環(huán)不變量/內(nèi)聯(lián)等等……類(lèi)型推斷是弱類(lèi)型語(yǔ)言特有的一種優(yōu)化方式

+1
回復(fù) kmxz

另外,V8 的 GC 主要使用的是分代/增量回收技術(shù),,而不是 python/perl 等語(yǔ)言使用的引用計(jì)數(shù)方式,,因此上半部分的分析雖然沒(méi)有問(wèn)題,,但是最后作結(jié)論的時(shí)候使用了引用計(jì)數(shù)這個(gè)詞有些不妥——當(dāng)然我不清楚是不是在指 GC,,也可能只是一個(gè)比喻的說(shuō)法而已,。

n?i?g?h?t?i?r?e? · 2014年05月04日

+1
回復(fù) n?i?g?h?t?i?r?e?

嗯,引用計(jì)數(shù)就是個(gè)比喻而已,,至于Ruby大人說(shuō)的可能是Ruby的JIT做法,和JS的做法還并不完全一樣,。 我把我之前提到的那篇文章找出來(lái)貼答案里了,,還是比較淺顯易懂的, 抄送 @kmxz

mcfog · 2014年05月04日

+4
回復(fù) kmxz

前半部分的回答沒(méi)有問(wèn)題,,不過(guò)后半部分稍有問(wèn)題,,舉的例子其實(shí)不是 JIT,,而是在 JIT 之后的類(lèi)型特化處理技術(shù)(Typing Specialization),。當(dāng)然了,,現(xiàn)在很多人喜歡用 JIT 代指一系列優(yōu)化技術(shù)的總稱(chēng),,不過(guò)還是說(shuō)明白較好,。答案里提到的方式,,也就是比如說(shuō)運(yùn)行若干次以后產(chǎn)生的編譯變體技術(shù),,不知道哪里有技術(shù)細(xì)節(jié)可以佐證。據(jù)松本大人在《代碼的未來(lái)》一書(shū)中的描述,,JIT 之后的特化是直接生成兩個(gè)版本的可執(zhí)行函數(shù),,一個(gè)是推測(cè)類(lèi)型,,執(zhí)行效率很高;另一個(gè)是泛化類(lèi)型,用于應(yīng)對(duì)非推測(cè)類(lèi)型傳參的情況,。也可能后者會(huì)在執(zhí)行次數(shù)上漲之后生成對(duì)應(yīng)的新版本也說(shuō)不定,這樣就和答案里說(shuō)的方式吻合了,。關(guān)于特化技術(shù),可以參考這兩篇論文: http://www.cs./~benh/research/papers/kedlaya13improved.pdf http://www.andrew./user/aktan/compilers/proposal.pdf 我不知道有多高的學(xué)術(shù)價(jià)值(俺是文盲),,只是看書(shū)的時(shí)候參考的瀏覽了一下,,大致了解了特化技術(shù)的原理。實(shí)際上本題問(wèn)得不是這個(gè),,略有跑題之嫌。

n?i?g?h?t?i?r?e? · 2014年05月04日

展開(kāi)評(píng)論

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買(mǎi)等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多