日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

V8系列——內(nèi)存管理(1)

 My鏡像站 2011-11-16

高效的程序離不開內(nèi)存的有效管理。自己對內(nèi)存管理的好處不少:減少內(nèi)存分配、回收開銷、避免內(nèi)存碎片、定位內(nèi)存位置、方便內(nèi)存整理、跟蹤內(nèi)存使用等等。V8 的堆內(nèi)存Heap用于存預(yù)編譯的code、JS對象內(nèi)存分配、運(yùn)行上下文對象分配、垃圾回收等。

一、內(nèi)存的建構(gòu)(Heap::Setup)

1、在V8完成OS操作的setup后,隨即建立和管理內(nèi)存;首先配置Heap參數(shù),Heap分為Young Generaion & Old Generation,Young Generation被劃分為兩個(gè)semispace,每個(gè)semispace大小默認(rèn)為2MB;Old Gernation 默認(rèn)大小為512MB;概念上講Young Generation = new spaceOld Generation = old space,即Heap又可以看成被劃分成若干個(gè)space(既有free space,也有PagedSpace,即空間的大小與內(nèi)存頁大小對齊),每個(gè)space專門負(fù)責(zé)相應(yīng)對象的內(nèi)存分配和回收。

2、Heap 接著配置內(nèi)存分配器MemoryAllocatorsingleton),讓之為heap生成ChunkInfo信息,其中包括了內(nèi)存地址、大小以及所屬的PagedSpace。Heap被劃分成若干個(gè)chunk,每個(gè)chunk大小=PagesPerChunk*PageSize = 64*8K(視操作系統(tǒng)內(nèi)存頁而定)= 512K。同時(shí)內(nèi)存分配器預(yù)留分配了一塊2*Young Generation大小(8MB)的虛擬內(nèi)存(initial_chunk_)。

后續(xù)所有內(nèi)存的分配都得通過MemoryAllocator進(jìn)行,setup時(shí)候設(shè)置了最大的sizeYoung Generation Size + Old Generation Size,即默認(rèn)為516MB。

3、接著Heap對該塊虛擬內(nèi)存進(jìn)行如下空間劃分:


其中CodeSpaceOldSpace共享4MB的空間劃分策略是否可以優(yōu)化?

4、每個(gè)spacesetup。

4.1)各個(gè)space的關(guān)系如下:


4.2)各個(gè)space的作用:

A. LargeObjectSpace :為了避免大對象的拷貝,使用該空間專門存儲(chǔ)大對象(大小超過Normal Page能容納的對象范圍),包括CodeSequetial String、FixedArray

B. MapSpace :存放對象的Map信息,即hidden_class;最大限制為8MB;每個(gè)Map對象固定大小,為了快速定位,所以將該空間單獨(dú)出來;

C. NewSpace :存放多種類型對象,最大限制為2MB;

D. CodeSpace :存放預(yù)編譯代碼(?);最大限制為512MB;

E. Old_Pointer_Space :存放GCsurviving的指針對象;最大限制為512MB;

F. Old_Data_Space :存放GCsurviving的數(shù)據(jù)對象;最大限制為512MB;

二、內(nèi)存的析構(gòu)(Heap::TearDown)

new_space_、old_pointer_space_、old_data_space_code_space_、map_space_、lo_space_依次析構(gòu),最后是內(nèi)存分配器MemoryAllocator::TearDown

三、空間的內(nèi)存分配

根據(jù)對象類型、對象生命狀態(tài),在對應(yīng)的空間中分配內(nèi)存,總的內(nèi)存申請入口在Heap::AllocateRaw。每個(gè)space的相同之處,都使用AllocationInfo記錄空間的toplimit,即當(dāng)前可用內(nèi)存起始地址和終止地址。但不同space的內(nèi)存分配邏輯不同,具體表現(xiàn)為:

1、 PagedSpace的內(nèi)存分配

由于PagedSpace空間由多個(gè)page組成,page的結(jié)構(gòu)如下:

為了避免申請的內(nèi)存跨頁(即避免內(nèi)存缺頁中斷,從而增加對象訪問延遲),所以分配內(nèi)存步驟可以劃分為:

1)如果申請內(nèi)存大小沒有超過current_page限制,則直接劃分出該大小區(qū)域,并往前移動(dòng)top指針(增加地址);

2)通過current_pageopaque_header查找到nextpage,并詢問其是否可用,是則把AllocationInfo更新為nextpage,返回(1);此外,對于current_page剩余的內(nèi)存塊,不同的派生類處理不同,MapSpace直接將之丟棄,可能是考慮到map大小固定,每個(gè)page浪費(fèi)掉PageSize%MapSize,空間不算大,不過它仍然有free list,收集map對象回收后的內(nèi)存;OldSpace則將之放入到一個(gè)free list,供后面使用;

3)從空間的free list查找是否有可用的內(nèi)存塊,MapSpace free list直接把頭結(jié)點(diǎn)劃分出去,而OldSpaceFreeList::Allocate復(fù)雜些,后續(xù)討論;

4)擴(kuò)展空間,MemoryAllocator::AllocatePages轉(zhuǎn)而請求分配虛擬內(nèi)存,在不超過最大空間限制前提下擴(kuò)展一個(gè)chunk,即64個(gè)page,返回(2);

5)返回Failure::RetryAfterGC,回收內(nèi)存垃圾并重試。后續(xù)會(huì)解釋如果利用該返回結(jié)果進(jìn)行GC并重試。

具體流程如下:


      從PagedSpace::Expand可以窺見該space的初始化邏輯如下:

a)指定需要分配的Page數(shù)目,交給內(nèi)存配置器MemoryAllocator執(zhí)行

bMemoryAllocator自身也有最大內(nèi)存數(shù)目的限制,不能保證剛才指定的page數(shù)目,只有最大限度地滿足,不然只有返回錯(cuò)誤;

c)初始化chunk中的所有Page信息;



2NewSpace的內(nèi)存分配:如果當(dāng)前空間滿足申請大小,則直接分配,否則返回Failure::RetryAfterGC,回收內(nèi)存垃圾并重試。

3、LargeObjectSpace的內(nèi)存分配

    由于該空間中每個(gè)Page都只會(huì)存放一個(gè)對象,所以當(dāng)申請內(nèi)存塊時(shí),直接通過MemoryAllocator::AllocateRawMemory分出一塊對象大小的內(nèi)存,并加入到該空間的內(nèi)存塊管理鏈表中。

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多