際際滷
Submit Search
糸温鉛厩庄一の赫遺をのぞいてみた
?
13 likes
?
9,490 views
Fumiyuki Yoshida
Follow
糸温鉛厩庄一で赫遺をしているw侭のソ`スをiんだので、そのまとめ。
Read less
Read more
1 of 48
Download now
Downloaded 118 times
More Related Content
糸温鉛厩庄一の赫遺をのぞいてみた
1.
dalvik の GC
をのぞいてみた @akachochin
2.
徭失B初 兆念@akachochin
3.
蝶メ`カ`で珂酷永やプリンタに稼艶岳恢壊糸な或皆を怏みzんで、咬み旗借いでいるひと。
4.
どうにかこうにか、コ`ディング根めた蝕k匍暦にありつけています。
5.
箸龍は兆念のとおり、橿戻菊めぐり。
6.
魁挑の廚瀘檗△気い芥`。
7.
書指GCをxんだわけ H氏でうっかり仝じゃあ、爰ってみようかな々と笥恠ったから(丶)
8.
ネタ冥しでWeb Pageみてたら仝2.3からコンカレントGCをサポ`ト々といてあった。
9.
もともと或皆塁でメモリ砿尖まわりは佶龍があった。
10.
こうしたわけで、コンカレント赫遺を嶄伉に赫遺のソ`スをiんでみたお三をしようと房いました。
11.
おさらい1 - GCとヒ`プ
ヒ`プとは、プログラムが強恬嶄に駅勣に鬉犬謄瓮皀蠅圀しくなったときに聞うためのメモリ糟囃である。
12.
プログラムが強議にメモリを鳩隠するとき、ヒ`プからメモリを俳り竃して、プログラムに局す。
13.
赫遺とは仝ヒ`プ貧で聞われなくなった糟囃を盾慧し、プログラムがヒ`プを壅旋喘することができるようにする々プログラムのことである。
14.
おさらい2 - もしGCがなかったら
赫遺がない桟廠でヒ`プが圀しくなった魁栽、苧幣議にヒ`プ護り輝て勣箔(掘恰.馨温鉛鉛看界())を佩い、ヒ`プが駅勣なくなった扮泣で苧幣議に盾慧(韓姻艶艶())する。
15.
繁寂は寂離える伏き麗。韓姻艶艶()を梨れたり、韓姻艶艶()したヒ`プを壅業韓姻艶艶()したり、いろいろやらかす。
16.
こういうバグは需つけるのがホントに寄筺
17.
Dalvikの古勣 Dalvikとは、AndoroidのGC。
18.
兆彭仝ガベ`ジコレクションのアルゴリズムとg廾々によれば、児云はマ`クΕ好ぉ`プなアルゴリズムでg廾されている???らしい。
19.
(けれどコンパイルオプション肝及ではCopy GCも聞えるらしいです。)
20.
さて、ソ`スをiむか???の念に念戻となる岑紛にXく乾れておきましょう。
21.
念戻1 -マ`クΕ好ぉ`プ- 聞われなくなったヒ`プを盾慧するアルゴリズムの匯つ
22.
ヒ`プ坪で聞われているオブジェクトを冥して咫をつけます。 ヒ`プ坪のオブジェクトの歌孚を桑にたどって、咫をつけていき (
マ`クフェ`ズ ) ??? 咫 咫 咫 咫
23.
念戻1 -マ`クΕ好ぉ`プ- ヒ`プをサ`チして、聞われてないヒ`プを盾慧(スイ`プフェ`ズ)する。
ヒ`プを枠^からサ`チし、咫のついてないヒ`プを盾慧していきます。 ☆ サ`チの^殻で仝咫々はしますが、蹐里錣りやすさのため、仝咫々を火しています。 咫 咫 咫 咫 盾慧 盾慧 盾慧
24.
念戻2 C ル`ト
- 枠の仝マ`クフェ`ズ々で仝聞われているオブジェクトを桑にたどって々ときました。
25.
たどるときの寄圷、枠^のオブジェクトを蒙に仝ル`ト々と冱います。箭えばJavaのオブジェクトの栽、參和楳のw侭がル`トになります。 gDvm
26.
GCをしているのはどこ? 採を蘓擇没靴辰討い海Δ???。
27.
書指はコンカレント赫遺を弖うわけだし。
28.
grep -ri concurrent
*
29.
すると、參和のw侭をk需する。
30.
vm/alloc/HeapSource.c: dvmCollectGarbageInternal(false,
GC_CONCURRENT);
31.
GCをしているのはどこ? つけたw侭はstatic void
*乙界禽温艶馨看稼意鞄姻艶温糸()というv方の嶄。
32.
距べてみると、どうもこいつはスレッドで、ヒ`プの腎きが匯協のしきい、鯱損悗辰進韻剖くだ。
33.
このv方は dvmCollectGarbageInternal() というv方を柵んでいる。兆念から冱ってもこいつが腎きメモリを指Г靴討い襪里世蹐Α
34.
dvmCollectGarbageInternal うわ、Lい(丶)
35.
及屈哈方はどうもこのv方を柵び竃した彜趨(尖喇)を局すものらしい。
36.
尖喇の匯Eはvm/alloc/Heap.hのGcReasonで協xされている。 GC_CONCURRENT はそのうちの匯つ。
37.
ソ`スを靖めてみると、 GC を柵び竃した尖喇によってI尖を笋┐討い襦書指は
GC_CONCURRENT なケ`スにスポットを輝ててh苧します。
38.
dvmCollectGarbageInternal GC_CONCURRENT な栽???
39.
1.GC を佩うスレッドの枠業を貧げない
40.
2.GC のI尖嶄に VM
坪の麿のスレッド ( ミュ`テ`タ ) が咾韻襪茲Δ砲垢I尖 (dvmResumeAllThreads(SUSPEND_FOR_GC);) がある。
41.
-> 噸宥は GC
を佩う栽、 VM 坪の麿のスレッドがメモリの彜Bを笋┐酉しくないので、 GC を佩うスレッド參翌の咾を峭めたいはず。
42.
dvmCollectGarbageInternal けれど、 13
ペ`ジにいた 2 つのI尖によって麿のスレッドが咾韻襪茲Δ砲覆襪燭瓠⇒┳の VM のに仝I尖が耕まる々護栽がpる。
43.
宥械の GC のイメ`ジ
44.
コンカレントな GC のイメ`ジ
宥械I尖 宥械I尖 GC 宥械I尖 宥械I尖 宥械I尖
45.
ここで融隼 ここで匯稀 dvmCollectGarbageInternal
をxれて、 メモリ護り輝てのv方(dvmMalloc())をiんでみます。
46.
いきなりマ`クΕ好ぉ`プな赫遺のI尖をiんでも仝んんっ殖殖拭垢箸いΩ个犬砲覆蠅泙后
47.
まず、メモリ護り輝てをする縞に、どんなことをするのか赫遺議な篇泣からみてみましょう。
48.
dvmMalloc()について 採らかのオブジェクトにメモリを護り輝てるHにはdvmMalloc()を柵んでメモリを_隠します。
49.
箭えば、閣珂貧で強く干温厩温プログラムがクラスを稼艶敬してオブジェクトを恬撹する魁栽、閣珂迦では糸厩馨粥鉛鉛看界或恢逮艶界岳()から糸厩馨珂温鉛鉛看界()を柵び竃して、オブジェクトのための糟囃を鳩隠します。
50.
dvmMalloc() dvmMalloc() ->
tryMalloc() ->dvmHeapSourceAlloc()をコ`ルします。
51.
この嶄で柵ばれている屈つのv方
52.
mspace_calloc()
53.
countAllocation() ->dvmHeapBitmapSetObjectBit()
54.
がとても嶷勣です。馨壊沿温界艶喝界温鉛鉛看界()はg縞のメモリ護り輝てを佩います。
55.
馨壊沿温界艶喝界温鉛鉛看界()のh苧は福待します。
56.
dvmHeapBitmapSetObjectBit() このv方柵び竃しを佩う貧で及匯哈方についているliveBitsがとても嶷勣です。
57.
肝のペ`ジ參週で赫遺にvSする閣珂迦のデ`タ更夛をまとめてみます。
58.
GCにvSしたデ`タ夛 GcHeap 夛悶
グロ`バルなヒ`プにvする秤 HeapSource MarkContext GcMarkContext 夛悶 F壓やっているGCの彜B HeapSource 夛悶 ヒ`プ腎gにvする秤 liveBits markBits liveBits MarkContext bitmap stack finger この2つのビット マップがとても嶷勣
59.
bitmap狼デ`タ夛 ビットマップ (liveBits,MarkBits)
の光ビットと仝ヒ`プ坪を 8byte ごとに曝俳った腎g々がそれぞれ蹐里茲Δ鬉靴討い襦 これによって、 8byte ごとの光ヒ`プ腎gの彜rをhする。 liveBits MarkBits ヒ`プI囃 ひとつのビットは ヒ`プ8byteI囃に 鬉靴討い ???? ????
60.
dvmHeapBitmapSetObjectBit() 護り輝てたヒ`プ腎gのうち、枠^8byteに輝たる腎gに鬉靴livebitを羨てる。
61.
箭えば子弼のヒ`プ24byteを護り輝てた栽はliveBitsは參和のになる。 1 liveBits
ヒ`プI囃 護り輝てたI囃の 枠^に鬉靴 ビットを1にする ????
62.
dvmHeapBitmapSetObjectBit() 箭えば、Javaプログラムでnew()してオブジェクトを護り輝てた栽、ヒ`プを護り輝てる。
63.
このヒ`プの枠遊はオブジェクトデ`タ。この嶄のデ`タ更夛を需ると護り輝てた糟囃のサイズはわかるため、枠遊だけ恢庄岳を羨てればよいと房われる。(護り輝てた糟囃蛍の恢庄岳を羨てる駅勣はない)
64.
とにかく、 ヒ`プを護り輝てると、 liveBits
を羨てる、というのが嶷勣 。
65.
壅び dvmCollectGarbageInternal (
I尖古勣 1) dvmCollectGarbageInternalはおおよそ、參和のことを佩ってコンカレントGCを佩っている。
66.
1.麿スレッドを強けないようにする(壊顎壊沿艶稼糸)
67.
2.光オブジェクトの姻看看岳に咫をつける
68.
3.界温姻糸糟囃のクリア(界温姻糸糟囃は朔峰)
69.
4.麿スレッドが壅業強けるように。(姻艶壊顎馨艶)
70.
5.咫のついたオブジェクトをたどって咫をつける
71.
壅び dvmCollectGarbageInternal (
I尖古勣 2) 6.麿スレッドを咾韻覆い茲Δ砲垢(suspend) 7.壅業ル`トをチェックして咫をつける 8.壅業マ`クのついたオブジェクトからたどって咫をつける 9.音勣なヒ`プを盾慧する。 10.麿スレッドが咾韻襪茲Δ砲垢(resume)
72.
壅び dvmCollectGarbageInternal (
の撹 ) これからは、參和の撹でをMめてみます。
73.
撹1.ル`トに咫をつける(1 C 4)
74.
更撹2.咫のついたオブジェクトが峺している麿のヒ`プに咫をつける(5-6)
75.
更撹3.麿スレッドが強恬することによりメモリの彜蓑が笋錣訖苗榻圓あるので、壅業咫をつける(7-8)
76.
更撹4.音勣なヒ`プを盾慧する(9)
77.
dvmCollectGarbageInternal ( ル`トのみに咫をつける
) dvmHeapMarkRootSet()をコ`ルして、ル`トに咫をつける。
78.
箭えば、干温厩温プログラムで稼艶敬されたオブジェクトの魁栽、ル`トに咫をつけるために糸厩馨赫界皆界温稼檎看看岳遺鉛温壊壊晦看温糸艶姻()が柵ばれる。
79.
この嶄で、グロ`バル篳乙禽厩馨が隔っているオブジェクトのル`トにして咫をつけています。
80.
dvmCollectGarbageInternal ( ル`トのみに咫をつける
) markClassObject()はdvmMarkObjectNonNull - markObjectNonNullを柵び竃す。 この嶄では、setAndReturnMarkBit()にmarkbitとobjを局す。objのアドレスに鬉靴markbitに咫をつける(1を羨てる) 1 MarkBits ヒ`プI囃 聞われているI囃の 枠^に鬉靴 ビットを 1 にする ????
81.
dvmCollectGarbageInternal ( ル`トのみに咫をつける
) dvmCollectGarbageInternal() から dvmClearCardTable() を柵び竃し、 CardTable を 0 クリアする。このr泣ではは護曚靴泙垢、兀えてほしいポイントは屈つ。 1. ひとつの cardTable はある蒙協のヒ`プメモリ 128byte に鬉垢襦
82.
2. ヒ`プメモリ貧のオブジェクトが隠隔する麿のオブジェクト歌孚の筝などの並鵑k伏すると、鬉垢 cardTable
は仝 Darty 々な彜Bになる。
83.
dvmCollectGarbageInternal ( ル`トのみに咫をつける
) cardtable と livebit のvS cardTable ???? liveBits アドレス秤鵑筝 などでヒ`プ貧の オブジェクトが筝 されると仝Darty々 な彜Bになる ???? livebit16(ヒ`プ 128byte)が匯つの CardTableに鬉垢
84.
dvmCollectGarbageInternal ( 咫のついたオブジェクトをたどる
) dvmHeapScanMarkedObjects()を柵び竃す。
85.
このv方の嶄では2つのv方を柵び竃している
86.
1.dvmHeapBitmapScanWalk()
87.
-> 枠^からmarkBitsを肝たどり、咫のついたヒ`プ(オブジェクト)が歌孚しているeのヒ`プ(オブジェクト)に咫をつける
88.
2.processMarkStack()
89.
-> 咫を原けるのを瘁指しにしたヒ`プ(オブジェクト)に咫をつける
90.
(仝朔指し々の吭龍はあとで。)
91.
dvmCollectGarbageInternal ( 咫のついたオブジェクトをたどる
) dvmHeapBitmapScanWalk()
92.
まず恷兜にmarkBitをたどって咫のついたw侭をつけます。 1 markBits
ヒ`プI囃 LiveBitをたどって 1をつけた ????
93.
dvmCollectGarbageInternal ( 咫のついたオブジェクトをたどる
) 肝にそのI囃の枠^をみます。箭えばJavaオブジェクトの栽は參和のとおりです。 ヒ`プI囃 ???? ヒ`プの eI囃 ヒ`プの eI囃 Javaオブジェクトの 栽、光メンバへの アドレスを隠隔して いる。
94.
dvmCollectGarbageInternal ( 咫のついたオブジェクトをたどる
) つけたヒ`プアドレスが、F壓冥沫鵑離勞`プアドレス (finger) よりも寄きなアドレス、栽、 markBits の鬋咼奪箸 1 を羨てる。 ヒ`プI囃 ???? 1 markBits F壓碧鵑 肝のビットは 仝finger々という markBitsの輝 ビットに咫 ???? 1 歌孚
95.
dvmCollectGarbageInternal ( 咫のついたオブジェクトをたどる
) 輝I囃坪でつけたヒ`プアドレスが、 finger よりも弌さなアドレス、栽、 markbit のビットに 1 を羨てないで、 stack というデ`タ夛坪にアドレスを隠贋する。 ヒ`プI囃 ???? markBits finger markBitsの輝 ビットに 咫を つけない ???? 1 歌孚
96.
dvmCollectGarbageInternal ( 瘁指しにしたオブジェクトに咫
) StackにAめてあるアドレスに鬉靴markBitに咫をつけていきます。
97.
1.壊岳温界一坪のアドレスを匯つ函り竃す
98.
2.1で函り竃したアドレスに鬉靴審床弘一京庄岳壊に咫をつける
99.
3.2で咫をつけた糟囃を冥し、艶のヒ`プを歌孚しているアドレスがいたらそれをヒ`プにめzみます。
100.
1から3を壊岳温界一の嶄附がなくなるまでRり卦します。
101.
dvmCollectGarbageInternal ( 瘁指しにしたオブジェクトに咫
) stack デ`タ夛 ヒ`プI囃 麿のアドレスを 歌孚しているか {べる 1 markBits アドレス 麿I囃を歌孚する アドレス アドレス、鬚劼箸槌,螻す つけたアドレス、鰺擦筑zむ アドレス、魏燐佞靴討い栽
102.
dvmCollectGarbageInternal ( 壅業咫をつける
) 31ペ`ジから36ペ`ジのI尖を佩っているgはミュ`テ`タが咾韻襪燭瓠▲勞`プの彜Bが笋錣訖苗榻圓ある。
103.
そのため、書業はミュ`テ`タが強けない彜蓑にした貧で壅業ヒ`プを距砲靴董∧荒置个料贄鬚穆拔飯,鬚弔韻襦
104.
dvmCollectGarbageInternal ( 壅業咫をつける
) dvmHeapReMarkRootSet()を柵び竃す。
105.
まず恷兜にル`トのみ咫をつけ岷す。咫の原け圭は児云議に27ペ`ジ、28ペ`ジと揖なので福待します。
106.
dvmCollectGarbageInternal ( 壅業咫をつける
) dvmHeapReScanMarkedObjects()を柵び竃し、ル`ト參翌のヒ`プのうち、筝のあったw侭に咫をつけます。
107.
ただし、壅業ヒ`プの枠遊からたどっているのでは紳覆いです。
108.
そこで、糸厩馨堰艶温沿檎艶皆界温稼珂温姻一艶糸或恢逮艶界岳壊()では匯垢健しています。
109.
dvmCollectGarbageInternal ( 壅業咫をつける
) 29ペ`ジ、30ペ`ジでh苧したcardTableをえていますか 嘔の蹐里茲Δ法鬉垢襯勞`プメモリ128byte貧にあるオブジェクトのアドレス秤鵑筝されるなどすると、cardTableはDartyになります。 A B C 書までオブジェクトBを歌孚して いたが、書業はオブジェクトB でなくオブジェクトCを歌孚 するようになった。
110.
dvmCollectGarbageInternal ( 壅業咫をつける
) 參和の蹐里茲Δ筝された辛嬬來の互いヒ`プI囃を原だし、輝I囃坪の畠てのオブジェクトに壅業咫をつけなおします。 ?????? ??? cardTable 筝された I囃k ??? オブジェクト をサ`チ markbits
111.
dvmCollectGarbageInternal ( 壅業咫をつける
) こうすることで、畠てのmarkbitをたどらなくてもよくなるため、筝された辛嬬來のあるオブジェクトをより富ない返gでgりzめます。
112.
dvmCollectGarbageInternal ( 音勣なヒ`プを盾慧する
) これでいよいよ音勣なヒ`プを盾慧する笋できました。
113.
糸厩馨堰艶温沿皆敬艶艶沿雨稼馨温姻一艶糸或恢逮艶界岳壊()を柵び竃し、音勣なヒ`プの盾慧を佩います。
114.
盾慧のメインとなるのは糸厩馨堰艶温沿京庄岳馨温沿皆敬艶艶沿安温鉛一()です。
115.
dvmCollectGarbageInternal ( 音勣なヒ`プを盾慧する
) ここでもう匯業畽。 ??? markbits ??? livebits 護り輝てgみメモリ の枠^アドレスにあたる ビットは1 GCのr泣で聞われている メモリI囃は1
116.
dvmCollectGarbageInternal ( 音勣なヒ`プを盾慧する
) この屈つのビットマップを聞って仝護り輝てされたけど、書は聞われていない々ヒ`プ了崔を護り竃します。そのために參和のようなビット處麻を佩います。
117.
live & ~mark
live ~mark & 吭龍 0 0 0 兜めから護り輝てられていない もしくは護り輝てられたI囃の余嶄 0 1 0 これはありえない 1 0 0 護り輝てられて、書も聞われている 1 1 1 護り輝てられたけど、書は聞われていない
118.
dvmCollectGarbageInternal ( 音勣なヒ`プを盾慧する
) 46ペ`ジで仟たに恬撹したビットマップで1が羨っているw侭に鬉靴織▲疋譽垢鯒鵑瓩(DECODE_BITSマクロ)、ビットが羨っているw侭にして盾慧I尖を柵び竃す。
119.
醤悶議には(酷晦雨皆堰喝永或鴛鰻意掘檎京雨酷マクロU喇で壊敬艶艶沿京庄岳馨温沿遺温鉛鉛恢温界一が柵ばれる。
120.
これによってめでたくメモリが盾慧されます。
121.
まとめ DalvikのGCはMark &
皆敬艶艶沿でした。
122.
コンカレント赫遺は、I尖の余嶄でミュ`テ`タが強けるようにすることでミュ`テ`タのI尖が海い扮寂嶄僅される並を契ぎます。
123.
2業朕の珂温姻一フェ`ズでは匯垢健することで壅業畠ヒ`プをたどらない垢健をしています。
124.
壊敬艶艶沿のために屈つのビットマップを貧返に聞っています。
125.
これ參貧岑りたければ、ソ`スiんでみてください。茶膿になります。
126.
お撰 兜めての茶氏k燕にもvわらず、ご賠ありがとうございました。
Download