V8引擎下的垃圾回收

今天看了一下關(guān)于垃圾回收的知識稽煤,來總結(jié)一下~
我們知道,JavaScript之所以能在瀏覽器環(huán)境和NodeJS環(huán)境運(yùn)行囚戚,都是因?yàn)橛蠽8引擎在幕后保駕護(hù)航酵熙。從編譯、內(nèi)存分配驰坊、運(yùn)行以及垃圾回收等整個(gè)過程匾二,都離不開它。

為什么要有垃圾回收

在C語言和C++語言中,我們?nèi)绻胍_辟一塊堆內(nèi)存的話察藐,需要先計(jì)算需要內(nèi)存的大小皮璧,然后自己通過malloc函數(shù)去手動分配,在用完之后分飞,還要時(shí)刻記得用free函數(shù)去清理釋放悴务,否則這塊內(nèi)存就會被永久占用,造成內(nèi)存泄露譬猫。

但是我們在寫JavaScript的時(shí)候惨寿,卻沒有這個(gè)過程,因?yàn)槿思乙呀?jīng)替我們封裝好了删窒,V8引擎會根據(jù)你當(dāng)前定義對象的大小去自動申請分配內(nèi)存裂垦。

不需要我們?nèi)ナ謩庸芾韮?nèi)存了,所以自然要有垃圾回收肌索,否則的話只分配不回收蕉拢,豈不是沒多長時(shí)間內(nèi)存就被占滿了嗎,導(dǎo)致應(yīng)用崩潰诚亚。

垃圾回收的好處是不需要我們?nèi)ス芾韮?nèi)存晕换,把更多的精力放在實(shí)現(xiàn)復(fù)雜應(yīng)用上,但壞處也來自于此站宗,不用管理了闸准,就有可能在寫代碼的時(shí)候不注意,造成循環(huán)引用等情況梢灭,導(dǎo)致內(nèi)存泄露夷家。
內(nèi)存泄漏:不再用到的內(nèi)存,沒有及時(shí)釋放敏释,內(nèi)存被占用库快,這就叫做內(nèi)存泄漏

1. 什么是垃圾?

即沒有被引用的對象都是垃圾
  1. 所有全局變量都不是垃圾
  2. 如果是存在函數(shù)內(nèi)的局部變量钥顽,當(dāng)這個(gè)函數(shù)執(zhí)行完了义屏,這個(gè)變量就消除了,但是在執(zhí)行過程中不能被消除蜂大,因?yàn)檫@個(gè)函數(shù)引用著它闽铐,全局變量又引用著這個(gè)函數(shù)
  3. 如果存在雙引用,把其中一個(gè)引用給置為null奶浦,還有另一個(gè)引用兄墅,也不會成為垃圾
  4. 如果存在環(huán)引用,如果引用你的對象全松開了手财喳,你就成為了垃圾
    環(huán)引用與外界至少要有一個(gè)橋梁察迟,外界有人引用著環(huán)斩狱,不然整個(gè)環(huán)就成了垃圾

2. 如何判斷是否可以回收

1) 標(biāo)記清除

當(dāng)變量進(jìn)入環(huán)境(例如,在函數(shù)中聲明一個(gè)變量)時(shí)扎瓶,就將這個(gè)變量標(biāo)記為“進(jìn)入環(huán)境”所踊。從邏輯上講,永遠(yuǎn)不能釋放進(jìn)入環(huán)境的變量所占用的內(nèi)存概荷,因?yàn)橹灰獔?zhí)行流進(jìn)入相應(yīng)的環(huán)境秕岛,就可能會用到它們。而當(dāng)變量離開環(huán)境時(shí)误证,則將其標(biāo)記為“離開環(huán)境”继薛。

可以使用任何方式來標(biāo)記變量。比如愈捅,可以通過翻轉(zhuǎn)某個(gè)特殊的位來記錄一個(gè)變量何時(shí)進(jìn)入環(huán)境遏考,或者使用一個(gè)“進(jìn)入環(huán)境的”變量列表及一個(gè)“離開環(huán)境的”變量列表來跟蹤哪個(gè)變量發(fā)生了變化。如何標(biāo)記變量并不重要蓝谨,關(guān)鍵在于采取什么策略灌具。

(1)垃圾收集器在運(yùn)行的時(shí)候會給存儲在內(nèi)存中的所有變量都加上標(biāo)記(當(dāng)然,可以使用任何標(biāo)記方式)譬巫。
(2)然后咖楣,它會去掉運(yùn)行環(huán)境中的變量以及被環(huán)境中變量所引用的變量的標(biāo)記
(3)此后,依然有標(biāo)記的變量就被視為準(zhǔn)備刪除的變量芦昔,原因是在運(yùn)行環(huán)境中已經(jīng)無法訪問到這些變量了诱贿。
(4)最后,垃圾收集器完成內(nèi)存清除工作咕缎,銷毀那些帶標(biāo)記的值并回收它們所占用的內(nèi)存空間珠十。
目前,IE锨阿、Firefox宵睦、Opera、Chrome和Safari的JavaScript實(shí)現(xiàn)使用的都是標(biāo)記清除式的垃圾回收策略(或類似的策略)墅诡,只不過垃圾收集的時(shí)間間隔互有不同。

當(dāng)一個(gè)對象和其關(guān)聯(lián)對象不再通過引用關(guān)系被當(dāng)前root引用了桐智,這個(gè)對象就會被垃圾回收末早。

2)引用計(jì)數(shù)

引用計(jì)數(shù)的垃圾收集策略不太常見。含義是跟蹤記錄每個(gè)值被引用的次數(shù)说庭。當(dāng)聲明了一個(gè)變量并將一個(gè)引用類型值賦給該變量時(shí)然磷,則這個(gè)值的引用次數(shù)就是1。

如果同一個(gè)值又被賦給另一個(gè)變量刊驴,則該值的引用次數(shù)加1姿搜。相反寡润,如果包含對這個(gè)值引用的變量改變了引用對象,則該值引用次數(shù)減1舅柜。

當(dāng)這個(gè)值的引用次數(shù)變成0時(shí)梭纹,則說明沒有辦法再訪問這個(gè)值了,因而就可以將其占用的內(nèi)存空間回收回來致份。

這樣变抽,當(dāng)垃圾收集器下次再運(yùn)行時(shí),它就會釋放那些引用次數(shù)為0的值所占用的內(nèi)存氮块。

Netscape Navigator 3.0是最早使用引用計(jì)數(shù)策略的瀏覽器绍载,但很快它就遇到了一個(gè)嚴(yán)重的問題:循環(huán)引用。

循環(huán)引用是指對象A中包含一個(gè)指向?qū)ο驜的指針滔蝉,而對象B中也包含一個(gè)指向?qū)ο驛的引用击儡,看個(gè)例子:

function foo () {
    var objA = new Object();
    var objB = new Object();
    
    objA.otherObj = objB;
    objB.anotherObj = objA;
}

這個(gè)例子中,objA和objB通過各自的屬性相互引用蝠引,也就是說曙痘,這兩個(gè)對象的引用次數(shù)都是2。

在采用標(biāo)記清除策略的實(shí)現(xiàn)中立肘,由于函數(shù)執(zhí)行后边坤,這兩個(gè)對象都離開了作用域,因此這種相互引用不是問題谅年。

但在采用引用次數(shù)策略的實(shí)現(xiàn)中茧痒,當(dāng)函數(shù)執(zhí)行完畢后,objA和objB還將繼續(xù)存在融蹂,因?yàn)樗鼈兊囊么螖?shù)永遠(yuǎn)不會是0旺订。

加入這個(gè)函數(shù)被重復(fù)多次調(diào)用,就會導(dǎo)致大量內(nèi)存無法回收超燃。為此区拳,Netscape在Navigator 4.0中也放棄了引用計(jì)數(shù)方式,轉(zhuǎn)而采用標(biāo)記清除來實(shí)現(xiàn)其垃圾回收機(jī)制意乓。

還要注意的是樱调,我們大部分人時(shí)刻都在寫著循環(huán)引用的代碼,看下面這個(gè)例子届良,相信大家都這樣寫過:

var el = document.getElementById('#el');
el.onclick = function (event) {
    console.log('element was clicked');
}

我們?yōu)橐粋€(gè)元素的點(diǎn)擊事件綁定了一個(gè)匿名函數(shù)笆凌,我們通過event參數(shù)是可以拿到相應(yīng)元素el的信息的。

大家想想士葫,這是不是就是一個(gè)循環(huán)引用呢乞而?
el有一個(gè)屬性onclick引用了一個(gè)函數(shù)(其實(shí)也是個(gè)對象),函數(shù)里面的參數(shù)又引用了el慢显,這樣el的引用次數(shù)一直是2爪模,即使當(dāng)前這個(gè)頁面關(guān)閉了欠啤,也無法進(jìn)行垃圾回收。

如果這樣的寫法很多很多屋灌,就會造成內(nèi)存泄露洁段。我們可以通過在頁面卸載時(shí)清除事件引用,這樣就可以被回收了:

var el = document.getElementById('#el');
el.onclick = function (event) {
    console.log('element was clicked');
}

// ...
// ...

// 頁面卸載時(shí)將綁定的事件清空
window.onbeforeunload = function(){
    el.onclick = null;
}

3. V8垃圾回收策略

自動垃圾回收有很多算法声滥,由于不同對象的生存周期不同眉撵,所以無法只用一種回收策略來解決問題,這樣效率會很低落塑。

所以纽疟,V8采用了一種代回收的策略,將內(nèi)存分為兩個(gè)生代:新生代(new generation)和老生代(old generation)憾赁。

新生代中的對象為存活時(shí)間較短的對象污朽,老生代中的對象為存活時(shí)間較長或常駐內(nèi)存的對象,分別對新老生代采用不同的垃圾回收算法來提高效率龙考,對象最開始都會先被分配到新生代(如果新生代內(nèi)存空間不夠蟆肆,直接分配到老生代),新生代中的對象會在滿足某些條件后晦款,被移動到老生代炎功,這個(gè)過程也叫晉升,后面會詳細(xì)說明缓溅。

分代內(nèi)存

默認(rèn)情況下蛇损,32位系統(tǒng)新生代內(nèi)存大小為16MB,老生代內(nèi)存大小為700MB坛怪,64位系統(tǒng)下淤齐,新生代內(nèi)存大小為32MB,老生代內(nèi)存大小為1.4GB袜匿。

新生代平均分成兩塊相等的內(nèi)存空間更啄,叫做semispace,每塊內(nèi)存大小8MB(32位)或16MB(64位)居灯。

新生代

1. 分配方式

新生代存的都是生存周期短的對象祭务,分配內(nèi)存也很容易,只保存一個(gè)指向內(nèi)存空間的指針穆壕,根據(jù)分配對象的大小遞增指針就可以了待牵,當(dāng)存儲空間快要滿時(shí),就進(jìn)行一次垃圾回收喇勋。

2. 算法

新生代采用Scavenge垃圾回收算法,在算法實(shí)現(xiàn)時(shí)主要采用Cheney算法偎行。

Cheney算法將內(nèi)存一分為二川背,叫做semispace贰拿,一塊處于使用狀態(tài),一塊處于閑置狀態(tài)熄云。

處于使用狀態(tài)的semispace稱為From空間膨更,處于閑置狀態(tài)的semispace稱為To空間

我畫了一套詳細(xì)的流程圖缴允,接下來我會結(jié)合流程圖來詳細(xì)說明Cheney算法是怎么工作的荚守。
垃圾回收在下面我統(tǒng)稱為 GC(Garbage Collection)

step1. 在From空間中分配了3個(gè)對象A练般、B矗漾、C

image.png

step2. GC進(jìn)來判斷對象B沒有其他引用,可以回收薄料,對象A和C依然為活躍對象

image.png

step3. 將活躍對象A敞贡、C從From空間復(fù)制到To空間

image.png

step4. 清空From空間的全部內(nèi)存

image.png

step5. 交換From空間和To空間

image.png

step6. 在From空間中又新增了2個(gè)對象D、E

image.png

step7. 下一輪GC進(jìn)來發(fā)現(xiàn)對象D沒有引用了摄职,做標(biāo)記

image.png

step8. 將活躍對象A誊役、C、E從From空間復(fù)制到To空間

image.png

step9. 清空From空間全部內(nèi)存

image.png

step10. 繼續(xù)交換From空間和To空間谷市,開始下一輪

image.png

通過上面的流程圖蛔垢,我們可以很清楚的看到,進(jìn)行From和To交換迫悠,就是為了讓活躍對象始終保持在一塊semispace中鹏漆,另一塊semispace始終保持空閑的狀態(tài)。

Scavenge由于只復(fù)制存活的對象及皂,并且對于生命周期短的場景存活對象只占少部分甫男,所以它在時(shí)間效率上有優(yōu)異的體現(xiàn)。Scavenge的缺點(diǎn)是只能使用堆內(nèi)存的一半验烧,這是由劃分空間和復(fù)制機(jī)制所決定的板驳。

由于Scavenge是典型的犧牲空間換取時(shí)間的算法,所以無法大規(guī)模的應(yīng)用到所有的垃圾回收中碍拆。但我們可以看到若治,Scavenge非常適合應(yīng)用在新生代中,因?yàn)樾律袑ο蟮纳芷谳^短感混,恰恰適合這個(gè)算法端幼。

3. 晉升

當(dāng)一個(gè)對象經(jīng)過多次復(fù)制仍然存活時(shí),它就會被認(rèn)為是生命周期較長的對象弧满。這種較長生命周期的對象隨后會被移動到老生代中婆跑,采用新的算法進(jìn)行管理。

對象從新生代移動到老生代的過程叫作晉升庭呜。

對象晉升的條件主要有兩個(gè):

對象從From空間復(fù)制到To空間時(shí)滑进,會檢查它的內(nèi)存地址來判斷這個(gè)對象是否已經(jīng)經(jīng)歷過一次Scavenge回收犀忱。如果已經(jīng)經(jīng)歷過了,會將該對象從From空間移動到老生代空間中扶关,如果沒有阴汇,則復(fù)制到To空間〗诨保總結(jié)來說搀庶,如果一個(gè)對象是第二次經(jīng)歷從From空間復(fù)制到To空間,那么這個(gè)對象會被移動到老生代中铜异。
當(dāng)要從From空間復(fù)制一個(gè)對象到To空間時(shí)哥倔,如果To空間已經(jīng)使用了超過25%,則這個(gè)對象直接晉升到老生代中熙掺。設(shè)置25%這個(gè)閾值的原因是當(dāng)這次Scavenge回收完成后未斑,這個(gè)To空間會變?yōu)镕rom空間篇梭,接下來的內(nèi)存分配將在這個(gè)空間中進(jìn)行对室。如果占比過高,會影響后續(xù)的內(nèi)存分配漩仙。

老生代

1. 介紹

在老生代中缆镣,存活對象占較大比重芽突,如果繼續(xù)采用Scavenge算法進(jìn)行管理,就會存在兩個(gè)問題:

由于存活對象較多董瞻,復(fù)制存活對象的效率會很低寞蚌。
采用Scavenge算法會浪費(fèi)一半內(nèi)存,由于老生代所占堆內(nèi)存遠(yuǎn)大于新生代钠糊,所以浪費(fèi)會很嚴(yán)重挟秤。
所以,V8在老生代中主要采用了Mark-Sweep和Mark-Sweep相結(jié)合的方式進(jìn)行垃圾回收抄伍。

2. Mark-Sweep

Mark-Sweep是標(biāo)記清除的意思艘刚,它分為標(biāo)記和清除兩個(gè)階段。

與Scavenge不同截珍,Mark-Sweep并不會將內(nèi)存分為兩份攀甚,所以不存在浪費(fèi)一半空間的行為。Mark-Sweep在標(biāo)記階段遍歷堆內(nèi)存中的所有對象岗喉,并標(biāo)記活著的對象秋度,在隨后的清除階段,只清除沒有被標(biāo)記的對象钱床。

也就是說荚斯,Scavenge只復(fù)制活著的對象,而Mark-Sweep只清除死了的對象【ㄓ担活對象在新生代中只占較少部分拐格,死對象在老生代中只占較少部分僧免,這就是兩種回收方式都能高效處理的原因刑赶。

我們還是通過流程圖來看一下:

step1. 老生代中有對象A、B懂衩、C撞叨、D、E浊洞、F


image.png

step2. GC進(jìn)入標(biāo)記階段牵敷,將A、C法希、E標(biāo)記為存活對象


image.png

step3. GC進(jìn)入清除階段枷餐,回收掉死亡的B、D苫亦、F對象所占用的內(nèi)存空間


image.png

可以看到毛肋,Mark-Sweep最大的問題就是,在進(jìn)行一次清除回收以后屋剑,內(nèi)存空間會出現(xiàn)不連續(xù)的狀態(tài)润匙。這種內(nèi)存碎片會對后續(xù)的內(nèi)存分配造成問題。

如果出現(xiàn)需要分配一個(gè)大內(nèi)存的情況唉匾,由于剩余的碎片空間不足以完成此次分配孕讳,就會提前觸發(fā)垃圾回收,而這次回收是不必要的巍膘。

2. Mark-Compact

為了解決Mark-Sweep的內(nèi)存碎片問題厂财,Mark-Compact就被提出來了。

Mark-Compact是標(biāo)記整理的意思峡懈,是在Mark-Sweep的基礎(chǔ)上演變而來的璃饱。Mark-Compact在標(biāo)記完存活對象以后,會將活著的對象向內(nèi)存空間的一端移動逮诲,移動完成后帜平,直接清理掉邊界外的所有內(nèi)存。如下圖所示:

step1. 老生代中有對象A梅鹦、B裆甩、C、D齐唆、E嗤栓、F(和Mark—Sweep一樣)

[圖片上傳失敗...(image-6e1023-1555941392151)]

step2. GC進(jìn)入標(biāo)記階段,將A、C茉帅、E標(biāo)記為存活對象(和Mark—Sweep一樣)
[圖片上傳失敗...(image-54ff18-1555941392151)]

step3. GC進(jìn)入整理階段叨叙,將所有存活對象向內(nèi)存空間的一側(cè)移動,灰色部分為移動后空出來的空間

[圖片上傳失敗...(image-e1f701-1555941392151)]

step4. GC進(jìn)入清除階段堪澎,將邊界另一側(cè)的內(nèi)存一次性全部回收

[圖片上傳失敗...(image-c2342f-1555941392151)]

3. 兩者結(jié)合

在V8的回收策略中擂错,Mark-Sweep和Mark-Conpact兩者是結(jié)合使用的。

由于Mark-Conpact需要移動對象樱蛤,所以它的執(zhí)行速度不可能很快钮呀,在取舍上,V8主要使用Mark-Sweep昨凡,在空間不足以對從新生代中晉升過來的對象進(jìn)行分配時(shí)爽醋,才使用Mark-Compact。

總結(jié)

V8的垃圾回收機(jī)制分為新生代和老生代便脊。

新生代主要使用Scavenge進(jìn)行管理蚂四,主要實(shí)現(xiàn)是Cheney算法,將內(nèi)存平均分為兩塊哪痰,使用空間叫From遂赠,閑置空間叫To,新對象都先分配到From空間中妒御,在空間快要占滿時(shí)將存活對象復(fù)制到To空間中解愤,然后清空From的內(nèi)存空間,此時(shí)乎莉,調(diào)換From空間和To空間送讲,繼續(xù)進(jìn)行內(nèi)存分配,當(dāng)滿足那兩個(gè)條件時(shí)對象會從新生代晉升到老生代惋啃。

老生代主要采用Mark-Sweep和Mark-Compact算法哼鬓,一個(gè)是標(biāo)記清除,一個(gè)是標(biāo)記整理边灭。兩者不同的地方是异希,Mark-Sweep在垃圾回收后會產(chǎn)生碎片內(nèi)存,而Mark-Compact在清除前會進(jìn)行一步整理绒瘦,將存活對象向一側(cè)移動称簿,隨后清空邊界的另一側(cè)內(nèi)存,這樣空閑的內(nèi)存都是連續(xù)的惰帽,但是帶來的問題就是速度會慢一些憨降。在V8中,老生代是Mark-Sweep和Mark-Compact兩者共同進(jìn)行管理的该酗。

以上就是本文的全部內(nèi)容授药,書寫過程中參考了很多中外文章士嚎,參考書籍包括樸大大的《深入淺出NodeJS》以及《JavaScript高級程序設(shè)計(jì)》等。我們這里并沒有對具體的算法實(shí)現(xiàn)進(jìn)行探討悔叽,感興趣的朋友可以繼續(xù)深入研究一下莱衩。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市娇澎,隨后出現(xiàn)的幾起案子笨蚁,更是在濱河造成了極大的恐慌,老刑警劉巖九火,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赚窃,死亡現(xiàn)場離奇詭異,居然都是意外死亡岔激,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進(jìn)店門是掰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來虑鼎,“玉大人,你說我怎么就攤上這事键痛§挪剩” “怎么了?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵絮短,是天一觀的道長江兢。 經(jīng)常有香客問我,道長丁频,這世上最難降的妖魔是什么杉允? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮席里,結(jié)果婚禮上叔磷,老公的妹妹穿的比我還像新娘。我一直安慰自己奖磁,他們只是感情好改基,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著咖为,像睡著了一般秕狰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上躁染,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天鸣哀,我揣著相機(jī)與錄音,去河邊找鬼褐啡。 笑死诺舔,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播低飒,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼许昨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了褥赊?” 一聲冷哼從身側(cè)響起糕档,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拌喉,沒想到半個(gè)月后速那,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡尿背,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年端仰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片田藐。...
    茶點(diǎn)故事閱讀 38,626評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡荔烧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出汽久,到底是詐尸還是另有隱情鹤竭,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布景醇,位于F島的核電站臀稚,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏三痰。R本人自食惡果不足惜吧寺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望酒觅。 院中可真熱鬧撮执,春花似錦、人聲如沸舷丹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽颜凯。三九已至谋币,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間症概,已是汗流浹背蕾额。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留彼城,地道東北人诅蝶。 一個(gè)月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓退个,卻偏偏與公主長得像,于是被迫代替她去往敵國和親调炬。 傳聞我的和親對象是個(gè)殘疾皇子语盈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評論 2 348

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

  • 前言 我們知道,JavaScript之所以能在瀏覽器環(huán)境和NodeJS環(huán)境運(yùn)行缰泡,都是因?yàn)橛蠽8引擎在幕后保駕護(hù)航刀荒。...
    liuxuan閱讀 484評論 1 1
  • 本文引用自這里這篇文章的所有內(nèi)容均來自 樸靈的《深入淺出Node.js》及A tour of V8:Garbage...
    楠小忎閱讀 1,413評論 0 2
  • Java引用的種類 1.對象在內(nèi)存中的狀態(tài) 對于JVM的垃圾回收機(jī)制來說,是否回收一個(gè)對象的標(biāo)準(zhǔn)在于:是否還有引用...
    Jack921閱讀 3,849評論 0 3
  • JVM內(nèi)存區(qū)域 JVM將其管理的內(nèi)存分為若干數(shù)據(jù)區(qū)域棘钞,這些數(shù)據(jù)區(qū)域分布情況如下圖所示: 程序計(jì)數(shù)器:一塊較小內(nèi)存區(qū)...
    luoxn28閱讀 693評論 0 0
  • JVM架構(gòu) 當(dāng)一個(gè)程序啟動之前缠借,它的class會被類裝載器裝入方法區(qū)(Permanent區(qū)),執(zhí)行引擎讀取方法區(qū)的...
    cocohaifang閱讀 1,650評論 0 7