boot.art@classes.dex和boot.art@classes.oat在系統(tǒng)第一次啟動時由系統(tǒng)類生成白粉。
boot.art@classes.dex是需要預(yù)加載的類對象。啟動后直接映射到內(nèi)存中,省去每次啟動時創(chuàng)建預(yù)加載的類對象
boot.art@classes.oat是預(yù)加載類的oat文件贱田。
Space
ImageSpace描述的是Image Space(連續(xù)空間)孟岛,DlMallocSpace描述的是Zygote Space和Allocation Space(連續(xù)空間,可分配针炉,匿名共享內(nèi)存塊)挠他,LargeObjectMapSpace描述的是Large Object Space(非連續(xù)空間,可分配)篡帕。
GC
6種垃圾收集器
串行和并行
FullMarkSweep(application and Zygote heap)殖侵、PartialMarkSweep(application heap but not the Zygote)和StickyMarkSweep(only free objects allocated since the last GC)
非并行GC
調(diào)用子類實現(xiàn)的成員函數(shù)InitializePhase執(zhí)行GC初始化階段。
掛起所有的ART運行時線程镰烧。
調(diào)用子類實現(xiàn)的成員函數(shù)MarkingPhase執(zhí)行GC標記階段拢军。
調(diào)用子類實現(xiàn)的成員函數(shù)ReclaimPhase執(zhí)行GC回收階段。
恢復(fù)第2步掛起的ART運行時線程怔鳖。
調(diào)用子類實現(xiàn)的成員函數(shù)FinishPhase執(zhí)行GC結(jié)束階段朴沿。
并行GC:
調(diào)用子類實現(xiàn)的成員函數(shù)InitializePhase執(zhí)行GC初始化階段。
獲取用于訪問Java堆的鎖败砂。
調(diào)用子類實現(xiàn)的成員函數(shù)MarkingPhase執(zhí)行GC并行標記階段赌渣。
釋放用于訪問Java堆的鎖。
掛起所有的ART運行時線程昌犹。
調(diào)用子類實現(xiàn)的成員函數(shù)HandleDirtyObjectsPhase處理在GC并行標記階段被修改的對象坚芜。。
恢復(fù)第4步掛起的ART運行時線程斜姥。
重復(fù)第5到第7步鸿竖,直到所有在GC并行階段被修改的對象都處理完成。
獲取用于訪問Java堆的鎖铸敏。
調(diào)用子類實現(xiàn)的成員函數(shù)ReclaimPhase執(zhí)行GC回收階段缚忧。
釋放用于訪問Java堆的鎖。
調(diào)用子類實現(xiàn)的成員函數(shù)FinishPhase執(zhí)行GC結(jié)束階段杈笔。
live bitmap為上次gc后存活的對象闪水,mark bitmap為當(dāng)前gc時存活的對象。
回收的對象為livebitmap為1蒙具,但是mark bitmap為0的對象
分配的對象對齊到8球榆,分配的對象的地址的最低三位總是0
bitmap(int數(shù)組)的大小為(heap size)/8/32*4
Mod Union Table
記錄不會被回收的Space的對象對會被回收的Space的引用
分配對象
當(dāng)滿足以下三個條件時朽肥,在large object heap上分配,否則在zygote或者allocation space上分配:
請求分配的內(nèi)存大于等于Heap類的成員變量large_object_threshold_指定的值持钉。這個值等于3 * kPageSize衡招,即3個頁面的大小。
已經(jīng)從Zygote Space劃分出Allocation Space每强,即Heap類的成員變量have_zygote_space_的值等于true始腾。
被分配的對象是一個原子類型數(shù)組,即byte數(shù)組空执、int數(shù)組和boolean數(shù)組等苛白。
分配完后剔氏,如果已分配空間大小大于concurrent_start_bytes_眨八,則執(zhí)行一次并行GC揣云。如果分配失敗伍伤,拋出OOM
LargeObjectMapSpace的分配是通過mmap創(chuàng)建一個匿名共享內(nèi)存践盼,zygote space和allocation space則是通過mspace分配內(nèi)存他去。
當(dāng)?shù)谝淮螄L試分配內(nèi)存失敗后浮还,會嘗試進行sticky桑孩,partial拜鹤,full gc(回收力度依次加大,不進行軟引用的回收)流椒,每次gc后都會嘗試分配內(nèi)存敏簿,如果成功就停止。
kGcTypeSticky只回收上次GC后在Allocation Space中新分配的垃圾對象宣虾;kGcTypePartial只回收Allocation Space的垃圾對象惯裕;kGcTypeFull同時回收Zygote Space和Allocation Space的垃圾對象
經(jīng)過前面三種類型的GC后還是不能成功分配到內(nèi)存,那就說明能夠回收的內(nèi)存還是太小了绣硝,因此蜻势,這時候只能通過在允許范圍內(nèi)增長堆的大小來滿足內(nèi)存分配請求了。如果在允許范圍內(nèi)增長了堆的大小還是不能成功分配到請求的內(nèi)存鹉胖,那就只能出最后的一個大招了握玛。
最后的大招是首先執(zhí)行一個類型為kGcTypeFull的、要求回收那些只被軟引用對象引用的對象的GC甫菠,接著再在允許范圍內(nèi)增長堆大小的前提下嘗試分配內(nèi)存挠铲。這一次如果還是失敗,那就真的是內(nèi)存不足了寂诱。