Heap map

 

519: zygote64
Address            Kbytes     PSS   Dirty    Swap  Mode  Mapping
// capacity_:536870912 = 524288k = 2048 + 522204
0000000012c00000    2084     564     556       0 rw---  dalvik-main space (deleted)
0000000012e09000  522204       0       0       0 -----  dalvik-main space (deleted)
0000000032c00000       4       0       0       0 rw---  dalvik-main space 1 (deleted)
0000000032c01000  524284       0       0       0 -----  dalvik-main space 1 (deleted)

0000000070c86000   15204     797     248       0 rw---  system@framework@boot.art  // image space 指定地址为0x70c86000
0000000071b5f000   38044    4136       0       0 r----  boot.oat
0000000074086000   41072    1456       0       0 r-x--  boot.oat
00000000768a2000       4       4       0       0 rw---  boot.oat

// non_moving_space_capacity:67108864 = 65536kb = 1756 + 4 + 55588 + 8188
00000000768a3000    1756     144      88       0 rw---  dalvik-zygote space (deleted)
0000000076a5a000       4       4       4       0 rw---  dalvik-non moving space (deleted)  
0000000076a5b000   55588       0       0       0 -----  dalvik-non moving space (deleted)
000000007a0a4000    8188       0       0       0 rw---  dalvik-non moving space (deleted)

000000007a8a3000  524288     459       0       0 rw---  dalvik-free list large object space (deleted)

000000555b3b5000      20       0       0       0 r-x--  app_process64
000000555b3c9000       4       0       0       0 r----  app_process64
000000555b3ca000       4       0       0       0 rw---  app_process64
000000557fe77000   29308    1409     464       0 rw---    [heap]
0000007f9eebd000    8192       0       0       0 rw---  dalvik-allocspace main rosalloc space mark-bitmap 3 (deleted)
0000007f9f6bd000    8192       0       0       0 rw---  dalvik-allocspace main rosalloc space live-bitmap 3 (deleted)
.................
0000007fa48be000     176      15       0       0 r----  system@framework@boot.art// image space mapped bitmap 地址由操作系统分配



01-01 20:19:43.085   519   519 E art     : HTC++++ image_filename: /data/dalvik-cache/arm64/system@framework@boot.art
01-01 20:19:43.085   519   519 E art     : HTC++++sizeof(image_header) = 140
01-01 20:19:43.085   519   519 E art     : HTC+++Image file for image heap: 15749120 vs 15566800
01-01 20:19:43.085   519   519 E art     : HTC++++xxxxxend_of_bitmap: 15749120
01-01 20:19:43.085   519   519 E art     : HTC++++xxxxxend_of_bitmap: 15749120
01-01 20:19:43.085   519   519 E art     : HTC++++mmap(0x70c86000, 15568896, 0x3, 0x2, 6, 0) of file '/data/dalvik-cache/arm64/system@framework@boot.art'  See process maps in the log.
01-01 20:19:43.085   519   519 E art     : HTC++++ bitmap size:180224bitmap offset:15568896
01-01 20:19:43.085   519   519 E art     : HTC++++mmap(0x0, 180224, 0x1, 0x2, 6, 15568896) of file '/data/dalvik-cache/arm64/system@framework@boot.art'  See process maps in the log.
01-01 20:19:43.085   519   519 E art     : HTC++++imagespace /data/dalvik-cache/arm64/system@framework@boot.art live-bitmap 0


sizeof(image_header) = 140
---------------------------------------------------------------------------------------
-rw-r--r-- root     root     15749120 2016-03-24 10:50 system@framework@boot.art
lrwxrwxrwx root     root              2016-03-24 10:50 system@framework@boot.oat -> /system/framework/arm64/boot.oat

system@framework@boot.art  15749120    //实际image file映射大小为 image_header.GetImageSize() =15566800
mmap(0x70c86000, 15568896, 0x3, 0x2, 6, 0)
映射的地址: 0x70c86000 映射到内存中的起始地址 image_header.GetImageBegin()
映射的字节数: 15568896 = 15204k 这个是image_header.GetImageSize()=15566800 = 0xed87d0 = 15201.95k页对齐后的数据
---------------------------------------------------------------------------------------
mmap(0x0, 180224, 0x1, 0x2, 6, 15568896)
在内存中映射地址为null,即为操作系统分配
bitmap size: 180224 = 0x2c000 = 176K
bitmap offset: 文件中的偏移位置为 15568896,显然在文件中是紧紧挨着image的
15749120 = 15568896 + 180224 显然刚好boot.art = image + bitmap,只不过他们在内存中映射的地址不相邻
---------------------------------------------------------------------------------------


0000000070c86000   15204     779     248       0 rw---  system@framework@boot.art
0000000071b5f000   38044    4186       0       0 r----  boot.oat


70c8 6000  => 0060 c870
ed 87d0    => d087 ed00
0030 8a76  => 0x768a3000  zygote space map address

0000000: 6172 740a 3031 3700 0060 c870 d087 ed00  art.017..`.p....
0000010: efa4 7d4d 00f0 b571 0000 b671 0c10 8a76  ..}M...q...q...v
0000020: 0030 8a76 0060 c800 5800 4571 0800 0000  .0.v.`..X.Eq....
0000030: 0100 0000 0000 0000 0821 ae00 0821 ae00  .........!...!..
0000040: 5087 0800 58a8 b600 e825 3000 40ce e600  P...X....%0.@...
0000050: 90b9 0600 0090 ed00 00c0 0200 f02c af71  .............,.q
0000060: 0000 0000 282d af71 0000 0000 602d af71  ....(-.q....`-.q
0000070: 0000 0000 982d af71 0000 0000 d02d af71  .....-.q.....-.q
0000080: 0000 0000 082e af71 0000 0000 0000 0000  .......q........
0000090: 60f2 4971 0000 0000 510d 0000 48f5 4971  `.Iq....Q...H.Iq
00000a0: d0f5 4971 58f6 4971 e0f6 4971 68f7 4971  ..IqX.Iq..Iqh.Iq
00000b0: 40f0 4971 0000 0000 082e 6d71 f0f7 4971  @.Iq......mq..Iq

 

 

03-27 18:02:41.416   519   519 E art     : HTC++++/data/dalvik-cache/arm64/system@framework@boot.art SpaceType:0 GcRetentionPolicy:0
03-27 18:02:41.417   519   519 E art     : HTC++++zygote / non moving space SpaceType:1 GcRetentionPolicy:1
03-27 18:02:41.418   519   519 E art     : HTC++++main rosalloc space SpaceType:1 GcRetentionPolicy:1
03-27 18:02:41.418   519   519 E art     : HTC++++main rosalloc space 1 SpaceType:1 GcRetentionPolicy:1
03-27 18:02:41.419   519   519 E art     : HTC++++free list large object space SpaceType:4 GcRetentionPolicy:1

03-27 18:02:45.768   519   519 E art     : HTC++++main rosalloc space SpaceType:1 GcRetentionPolicy:1
03-27 18:02:45.768   519   519 E art     : HTC++++Zygote space SpaceType:2 GcRetentionPolicy:2
03-27 18:02:45.768   519   519 E art     : HTC++++non moving space SpaceType:1 GcRetentionPolicy:1


03-27 18:02:42.642   520   520 E art     : HTC++++/data/dalvik-cache/arm/system@framework@boot.art SpaceType:0 GcRetentionPolicy:0
03-27 18:02:42.643   520   520 E art     : HTC++++zygote / non moving space SpaceType:1 GcRetentionPolicy:1
03-27 18:02:42.643   520   520 E art     : HTC++++main rosalloc space SpaceType:1 GcRetentionPolicy:1
03-27 18:02:42.644   520   520 E art     : HTC++++main rosalloc space 1 SpaceType:1 GcRetentionPolicy:1
03-27 18:02:42.644   520   520 E art     : HTC++++mem map large object space SpaceType:4 GcRetentionPolicy:1
03-27 18:02:56.060   520   520 E art     : HTC++++main rosalloc space SpaceType:1 GcRetentionPolicy:1
03-27 18:02:56.060   520   520 E art     : HTC++++Zygote space SpaceType:2 GcRetentionPolicy:2
03-27 18:02:56.060   520   520 E art     : HTC++++non moving space SpaceType:1 GcRetentionPolicy:1

 

Compacting GC对Bump Pointer Space的使用是略有不同的,因此,我们又分为Semi-Space GC、Generational Semi-Space GC和Mark-Compact GC三种情况来介绍Bump Pointer Space。

Semi-Space GC:

它由两个Bump Pointer Space组成

Bump Pointer Space 1和Bump Pointer Space 2分别称为From Space和To Space。其中,对象的分配发生在From Space中。在Bump Pointer Space中,有一个指针end_,始终指向下一次要分配的内存块的起始地址。因此,在Bump Pointer Space上分配内存的逻辑是很简单的,只要前指针end_向前移动指定的大小即可。这也是Bump Pointer的由来。当From Space不能满足内存分配要求时,就会触发一次Semi-Space GC,结果就是From Space和To Space互换了位置,并且原来在From Space上的Live Object按地址值从小到大的顺序移动到了原来的To Space上去。

Generational Semi-Space GC:

 

Generational Semi-Space GC与Semi-Space GC是基本相同的,只不过前者在移动对象时,会考虑到对象的年龄。如果一个对象在多次GC中都能存活下来,那么就会将它移动到一个Promote Space中去。这是因为时间局部性原理,一个对象如果在前面几次GC中都能存活下来,那么它在下一次GC中也很有可能是存活的。因此,就把它移动到一个 Promote Space中去。由于Promote Space是一个Non-Moving Space,因此以后在这个Space上的对象不会再被移动。通过这种方式,就可以有效地减少在Generational Semi-Space GC中要移动的对象的个数,从而提高GC效率。

Obj-1是一个在多次GC中存活下来的对象,因此,在下一次Generational Semi-Space中,它就被移动到了Promote Space中,而Obj-3就像Semi-Space GC中的Live Object一样,被移动到了To Space中。

Mark-Compact GC

 

在执行Mark-Compact GC时,所有存活的对象都被移动到了另外一端,通过这种方式就达到压缩的效果。

Semi-Space和Generational Semi-Space需要用到两个Bump Pointer Space,这也是Semi-Space的由来,然而Mark-Compact GC只用到了一个Bump Pointer Space

 

Ros Alloc Space和Dl Malloc Space:

但是Ros Alloc Space不像Dl Malloc Space一样使用C库内存管理接口来分配和释放内存,而是采用一种称为Ros(Runs-of-slots)的接口来进行内存分配和释放。

       Ros算法其实与Linux内核使用的SLAB算法类似,它们的核心思想都是将内存分为若干个Bucket,每一个Bucket都管理着相同大小的内存 块。这样在分配内存时,就会先根据要分配的内存大小找到最合适的Bucket,然后再从这个Bucket找到一块空闲的内存进行分配。这是一种Best Fit分配策略,好处是可以将大小相同的对象集中在一起分配,这样可以有效地减少内存碎片。

[dalvik.vm.heapgrowthlimit]: [192m]
[dalvik.vm.heapmaxfree]: [8m]
[dalvik.vm.heapminfree]: [2m]
[dalvik.vm.heapsize]: [512m]
[dalvik.vm.heapstartsize]: [8m]
[dalvik.vm.heaptargetutilization]: [0.75]

01-01 00:15:37.665   524   524 E art     : HTC++++ requested_alloc_space_begin:0x766bf000
01-01 00:15:37.666   524   524 E art     : HTC+++++ capacity_536870912
01-01 00:15:37.666   524   524 E art     : HTC+++++DlMallocSpace::CreateFromMemMap() kDefaultStartingSize:4096, initial_size:8388608, size:67108864
01-01 00:15:37.666   524   524 E art     : HTC+++++Runtime::Current()->RunningOnValgrind():0
01-01 00:15:37.666   524   524 E art     : HTC++++ heap_capacity:67108864, bitmap_size:1048576
01-01 00:15:37.666   524   524 E art     : HTC++++ heap_capacity:67108864, bitmap_size:1048576
01-01 00:15:37.666   524   524 E art     : HTC++++zygote / non moving space SpaceType:1 GcRetentionPolicy:1
01-01 00:15:37.666   524   524 E art     : HTC+++++growth_limit_:201326592, initial_size:8388608

01-01 00:15:37.668   524   524 E art     : HTC++++main rosalloc space SpaceType:1 GcRetentionPolicy:1
01-01 00:15:37.668   524   524 E art     : HTC+++kUseRosAlloc:1
01-01 00:15:37.668   524   524 E art     : HTC+++CardTable::kCardSize:128
         image_header.GetImageSection(ImageHeader::kSectionObjects).End(): 11411720
HTC++++kBitsPerByte:8, kAlignment:8
01-01 16:58:53.981   538   538 E art     : HTC+++::CreateFromMemMap() name:imagespace /data/dalvik-cache/arm64/system@framework@boot.art live-bitmap 0, heap_capacity:11534336
01-01 16:58:53.981   538   538 E art     : HTC++++heap_begin:0x6f3ff000
//依据bitmap 算出imagespace的大小 180224 * 64 = 11534336
01-01 16:58:53.981   538   538 E art     : HTC++++ heap_capacity:11534336, bitmap_size:180224 = 176K ///image space: 11534336 = 11264k=11M
01-01 16:58:53.981   538   538 E art     : HTC+++++ image_header.GetImageSection(ImageHeader::kSectionObjects).End(): 11411720

kDefaultStartingSize:4096 = 4K
growth_limit_:201326592 = 192M
initial_size:8388608 = 8M

heap_capacity:67108864 = 65536k = 1024K * 64 = 64M
bitmap_size:1048576 = 1024K

capacity_:536870912 = 512M
size:67108864 = 65536K = 64M = non_moving_space_capacity
non_moving_space_capacity:64M


1712689152
 107374182
536870912 *2 =107374182

sizeof(image_header) = 140

01-01 00:15:37.568   524   524 E art     : HTC++++sizeof(image_header) = 140
01-01 00:15:37.568   524   524 E art     : HTC+++Image file for image heap: 15749120 vs 15566800
01-01 00:15:37.568   524   524 E art     : HTC++++xxxxxend_of_bitmap: 15749120
01-01 00:15:37.568   524   524 E art     : HTC++++mmap(0x70aa2000, 15568896, 0x3, 0x2, 6, 0) of file '/data/dalvik-cache/arm64/system@framework@boot.art'  See process maps in the log.
01-01 00:15:37.568   524   524 E art     : HTC+++++ map actual: 0x70aa2000
01-01 00:15:37.568   524   524 E art     : HTC++++ bitmap size:180224bitmap offset:15568896
01-01 00:15:37.568   524   524 E art     : HTC++++mmap(0x0, 180224, 0x1, 0x2, 6, 15568896) of file '/data/dalvik-cache/arm64/system@framework@boot.art'  See process maps in the log.
01-01 00:15:37.568   524   524 E art     : HTC+++++ map actual: 0x7fa1810000


524: zygote64
Address            Kbytes     PSS   Dirty    Swap  Mode  Mapping
 // 0x12c00000 = 300M
 // capacity_:536870912 = 512M = 2084k + 522204k main_mem_map_1
0000000012c00000    2084     558     548       0 rw---  dalvik-main space (deleted)
0000000012e09000  522204       0       0       0 -----  dalvik-main space (deleted)
 // capacity_:536870912 = 512M = 4k + 524284k    main_mem_map_2
0000000032c00000       4       0       0       0 rw---  dalvik-main space 1 (deleted)
0000000032c01000  524284       0       0       0 -----  dalvik-main space 1 (deleted)

empty:478M

//Align(15566800, 4K) = 15204k = 14.8M (其中0~11M对应bitmap)
0000000070aa2000   15204     827     244       0 rw---  system@framework@boot.art ///////////
// Align(81015552, 4k) = (38044 + 41072 + 4) * 1024 = 77.3M
000000007197b000   38044    4170       0       0 r----  boot.oat
0000000073ea2000   41072    1463       0       0 r-x--  boot.oat
00000000766be000       4       4       0       0 rw---  boot.oat
// requested_alloc_space_begin:0x766bf000
// size:67108864 = 64M = 65536K = 1760k + 4k + 55584k + 8188k 
00000000766bf000    1760     148      88       0 rw---  dalvik-zygote space (deleted)
0000000076877000       4       4       4       0 rw---  dalvik-non moving space (deleted)
0000000076878000   55584       0       0       0 -----  dalvik-non moving space (deleted)
0000000079ec0000    8188       0       0       0 rw---  dalvik-non moving space (deleted)

//    = 524288K = 512M
000000007a6bf000  524288     491       0       0 rw---  dalvik-free list large object space (deleted)

00000055587b7000      20       0       0       0 r-x--  app_process64
00000055587cb000       4       0       0       0 r----  app_process64
00000055587cc000       4       0       0       0 rw---  app_process64
000000555ed55000   29312    1448     436       0 rw---    [heap]
0000007f8d552000    8192       0       0       0 rw---  dalvik-allocspace main rosalloc space mark-bitmap 3 (deleted)
0000007f8dd52000    8192       0       0       0 rw---  dalvik-allocspace main rosalloc space live-bitmap 3 (deleted)
0000007f8e552000  102400       0       0       0 -----    [anon]
0000007f94952000       8       4       0       0 r-x--  libwebviewchromium_loader.so
..................
0000007f9b8e8000       4       0       0       0 r----    [anon:linker_alloc]
0000007f9b8e9000       4       0       0       0 r----    [anon]
0000007f9b8ea000     240     102       0       0 r--s-  framework-res.apk
0000007f9b926000      68       2       0       0 rw---    [anon:libc_malloc]
0000007f9b937000     128       4       4       0 rw---  dalvik-LinearAlloc (deleted)
0000007f9b957000      24       0       0       0 r-x--  libged.so
0000007f9b95d000      60       0       0       0 -----    [anon]
0000007f9b96c000       4       0       0       0 r----  libged.so
.................
0000007f9bae7000      92       3       0       0 rw---    [anon:libc_malloc]
0000007f9bf0e000     128       4       4       0 rw---  dalvik-rosalloc page map (deleted)
0000007f9bf2e000   22568     185       0       0 r--s-  icudt55l.dat
0000007f9d538000     128       4       0       0 rw---  dalvik-LinearAlloc (deleted)
0000007f9d558000     328      88       0       0 r-x--  libjavacore.so
0000007f9d5aa000      64       0       0       0 -----    [anon]
0000007f9d5ba000       8       0       0       0 r----  libjavacore.so
0000007f9d5bc000      12       4       4       0 rw---  libjavacore.so
0000007f9d5bf000       4       0       0       0 rw---    [anon]
0000007f9d5c0000       8       4       4       0 rw---  dalvik-indirect ref table (deleted)
0000007f9d5c2000     800       0       0       0 rw---  dalvik-indirect ref table (deleted)
0000007f9d68a000     800       4       4       0 rw---  dalvik-indirect ref table (deleted)
0000007f9d752000       8       0       0       0 rw---  dalvik-mark sweep sweep array free buffer (deleted)
0000007f9d754000       8       0       0       0 rw---  dalvik-mark sweep sweep array free buffer (deleted)
0000007f9d756000       8       0       0       0 rw---  dalvik-mark sweep sweep array free buffer (deleted)
0000007f9d758000    8196     233     224       0 rw---  dalvik-live stack (deleted)
0000007f9df59000    8196       0       0       0 rw---  dalvik-allocation stack (deleted)
// mark stack
0000007f9e75a000     256       0       0       0 rw---  dalvik-mark stack (deleted)
// card table
0000007f9e79a000   13272      36      36       0 rw---  dalvik-card table (deleted)
// LOS INFO
0000007f9f490000    1024       1       0       0 rw---  dalvik-large object free list space allocation info map (deleted)
0000007f9f590000     128       0       0       0 rw---  dalvik-large marked objects (deleted)
0000007f9f5b0000     128       0       0       0 rw---  dalvik-large live objects (deleted)
// memory 512M  => live bitmap 8M = 512/64 M 
0000007f9f5d0000    8192       0       0       0 rw---  dalvik-allocspace main rosalloc space 1 mark-bitmap 2 (deleted)
0000007f9fdd0000    8192       0       0       0 rw---  dalvik-allocspace main rosalloc space 1 live-bitmap 2 (deleted)
0000007fa05d0000     128       0       0       0 rw---  dalvik-rosalloc page map (deleted)
0000007fa0feb000       4       0       0       0 -----    [anon]
0000007fa0fec000      16       0       0       0 rw---    [anon:thread signal stack]
0000007fa0ff0000       4       0       0       0 -----    [anon]
0000007fa0ff1000      16       0       0       0 rw---    [anon:thread signal stack]
0000007fa0ff5000       4       0       0       0 -----    [anon]
0000007fa0ff6000      16       0       0       0 rw---    [anon:thread signal stack]
0000007fa0ffa000       4       0       0       0 -----    [anon]
0000007fa0ffb000      16       0       0       0 rw---    [anon:thread signal stack]
0000007fa0fff000       4       0       0       0 -----    [anon]
0000007fa1000000       4       0       0       0 -----    [anon]
0000007fa1001000    1036       8       8       0 rw---    [stack:5606]
0000007fa1104000       8       4       4       0 rw---  dalvik-indirect ref table (deleted)
0000007fa1106000       4       0       0       0 -----    [anon]
0000007fa1107000       4       0       0       0 -----    [anon]
0000007fa1108000    1036       8       8       0 rw---    [stack:5605]
0000007fa120b000       8       4       4       0 rw---  dalvik-indirect ref table (deleted)
0000007fa120d000       4       0       0       0 -----    [anon]
0000007fa120e000       4       0       0       0 -----    [anon]
0000007fa120f000    1036       8       8       0 rw---    [stack:5604]
0000007fa1312000       8       4       4       0 rw---  dalvik-indirect ref table (deleted)
0000007fa1314000       4       0       0       0 -----    [anon]
0000007fa1315000       4       0       0       0 -----    [anon]
0000007fa1316000    1036       8       8       0 rw---    [stack:5603]
0000007fa1419000       8       4       4       0 rw---  dalvik-indirect ref table (deleted)
0000007fa141b000       4       0       0       0 rw---  dalvik-mod union bitmap (deleted)
0000007fa141c000    1000       0       0       0 rw---  dalvik-allocspace non moving space mark-bitmap 4 (deleted)
0000007fa1516000    1000       0       0       0 rw---  dalvik-allocspace non moving space live-bitmap 4 (deleted)
0000007fa1610000    1024       0       0       0 rw---   non moving space mark-bitmap 0 (deleted)
0000007fa1710000    1024       0       0       0 rw---   non moving space live-bitmap 0 (deleted)
0000007fa1810000     176      15       0       0 r----  system@framework@boot.art  //////////////
0000007fa183c000       4       0       0       0 r-x--  libsigchain.so
0000007fa183d000      60       0       0       0 -----    [anon]
0000007fa184c000       4       0       0       0 r----  libsigchain.so
0000007fa184d000       4       0       0       0 rw---  libsigchain.so
0000007fa184e000    6064    1197       0       0 r-x--  libart.so
0000007fa1e3a000      60       0       0       0 -----    [anon]
0000007fa1e49000      76       2       0       0 r----  libart.so
0000007fa1e5c000       8       8       8       0 rw---  libart.so
0000007fa1e5e000      12       4       4       0 rw---    [anon]
0000007fa1e61000       4       2       0       0 r----  boot.oat
0000007fa1e62000       4       0       0       0 r----    [anon:linker_alloc]
0000007fa1e63000       4       0       0       0 rw---    [anon:linker_alloc_vector]
0000007fa1e64000       8       4       4       0 r----    [anon:linker_alloc]
0000007fa1e66000       4       0       0       0 r--s-  setfil
0000007fa1e67000      12       0       0       0 r----    [anon]


mutian@mutian:~/test/test$ ll
total 94508
-rw-r--r-- 1 mutian mutian 15749120 Mar 28 19:17 system@framework@boot.art
-rw-r--r-- 1 mutian mutian 81015552 Mar 28 19:18 system@framework@boot.oat



15749120 = 15380k
0020 aa70 => 70aa2000 image_begin_
d087 ed00 => 00ed87d0 = 15566800 = image_size_
00f0 6b76 => 766bf000 It must be requested_alloc_space_begin
00b0 9771 => 7197b000 oat_file_begin_
00f0 6b76 => 766bf000 oat_file_end_  is the begin of requested_alloc_space_begin

0000000: 6172 740a 3031 3700 0020 aa70 d087 ed00  art.017.. .p....
0000010: efa4 7d4d 00b0 9771 00c0 9771 0cd0 6b76  ..}M...q...q..kv
0000020: 00f0 6b76 0020 aa00 58c0 2671 0800 0000  ..kv. ..X.&q....
0000030: 0100 0000 0000 0000 0821 ae00 0821 ae00  .........!...!..
0000040: 5087 0800 58a8 b600 e825 3000 40ce e600  P...X....%0.@...
0000050: 90b9 0600 0090 ed00 00c0 0200 f0ec 9071  ...............q
0000060: 0000 0000 28ed 9071 0000 0000 60ed 9071  ....(..q....`..q
0000070: 0000 0000 98ed 9071 0000 0000 d0ed 9071  .......q.......q
0000080: 0000 0000 08ee 9071 0000 0000 0000 0000  .......q........
0000090: 60b2 2b71 0000 0000 510d 0000 48b5 2b71  `.+q....Q...H.+q
00000a0: d0b5 2b71 58b6 2b71 e0b6 2b71 68b7 2b71  ..+qX.+q..+qh.+q
00000b0: 40b0 2b71 0000 0000 08ee 4e71 f0b7 2b71  @.+q......Nq..+q

 

class PACKED(4) ImageHeader {
 public:
  ImageHeader() : compile_pic_(0) {}

  ImageHeader(uint32_t image_begin,
              uint32_t image_size_,
              ImageSection* sections,
              uint32_t image_roots,
              uint32_t oat_checksum,
              uint32_t oat_file_begin,
              uint32_t oat_data_begin,
              uint32_t oat_data_end,
              uint32_t oat_file_end,
              uint32_t pointer_size,
              bool compile_pic_);

  enum ImageMethod {
    kResolutionMethod,  //用来描述一个还未进行解析和链接的ART方法
    kImtConflictMethod,
    kImtUnimplementedMethod,
    kCalleeSaveMethod, //用来描述一个由被调用者保存的r4-r11、lr和s0-s31寄存器的ART方法,即由被调用者保存非参数使用的通用寄存器以及所有的浮点数寄存器。
    kRefsOnlySaveMethod, //用来描述一个由被调用者保存的r5-r8、r10-r11和lr寄存器的ART方法,即由被调用者保存非参数使用的通用寄存器。
    kRefsAndArgsSaveMethod, //用来描述一个由被调用者保存的r1-r3、r5-r8、r10-r11和lr寄存器的ART方法,即由被调用者保存参数和非参数使用的通用寄存器。
    kImageMethodsCount,  // Number of elements in enum.
  };

  enum ImageRoot {
    kDexCaches,
    kClassRoots,
    kImageRootsMax,
  };

  enum ImageSections {
    kSectionObjects,
    kSectionArtFields,
    kSectionArtMethods,
    kSectionInternedStrings,
    kSectionImageBitmap,
    kSectionCount,  // Number of elements in enum.
  };

  ArtMethod* GetImageMethod(ImageMethod index) const;
  void SetImageMethod(ImageMethod index, ArtMethod* method);

  const ImageSection& GetImageSection(ImageSections index) const;
  const ImageSection& GetMethodsSection() const {
    return GetImageSection(kSectionArtMethods);
  }

  mirror::Object* GetImageRoot(ImageRoot image_root) const
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
  mirror::ObjectArray<mirror::Object>* GetImageRoots() const
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);

  void RelocateImage(off_t delta);

  bool CompilePic() const {
    return compile_pic_ != 0;
  }

 private:
  static const uint8_t kImageMagic[4];
  static const uint8_t kImageVersion[4];

  uint8_t magic_[4];   // Image文件魔数,固定为'art\n'
  uint8_t version_[4];  // Image文件版本号,目前设置为'005\0'

  // Required base address for mapping the image.
  uint32_t image_begin_;

  // Image size, not page aligned.
  uint32_t image_size_;

  // Checksum of the oat file we link to for load time sanity check.
  uint32_t oat_checksum_; //与Image文件关联的boot.art@classes.oat文件的检验值。

  // Start address for oat file. Will be before oat_data_begin_ for .so files.
  uint32_t oat_file_begin_; //与Image文件关联的boot.art@classes.oat文件映射到内存的起始位置。

  // Required oat address expected by image Method::GetCode() pointers.
  uint32_t oat_data_begin_; //与Image文件关联的boot.art@classes.oat文件的OATDATA段映射到内存的起始位置。

  // End of oat data address range for this image file.
  uint32_t oat_data_end_; //与Image文件关联的boot.art@classes.oat文件的OATDATA段映射到内存的结束位置。

  // End of oat file address range. will be after oat_data_end_ for
  // .so files. Used for positioning a following alloc spaces.
  uint32_t oat_file_end_; //与Image文件关联的boot.art@classes.oat文件映射到内存的结束位置。

  // The total delta that this image has been patched.
  int32_t patch_delta_;

  // Absolute address of an Object[] of objects needed to reinitialize from an image.
  uint32_t image_roots_; //一个Object对象地址数组地址,这些Object对象就是在Image Space上分配的对象。

  // Pointer size, this affects the size of the ArtMethods.
  uint32_t pointer_size_;

  // Boolean (0 or 1) to denote if the image was compiled with --compile-pic option
  const uint32_t compile_pic_;

  // Image sections
  ImageSection sections_[kSectionCount];

  // Image methods.
  uint64_t image_methods_[kImageMethodsCount];

  friend class ImageWriter;
};

每次Heap类的成员函数PreZygoteFork被调用时,都会调用成员函数CollectGarbage执行一次垃圾收集,也就是Zygote进程每次fork子进程之前,都执行一次垃圾收集,这样就可以使得fork出来的子进程有一个紧凑的堆空间。
在划分Zygote Space之前,先将保存在Allocation Stack里面的对象标记到对应的Space的Live Bitmap去,这是通过调用Heap类的成员函数FlushAllocStack来实现的。对于新分配的对象,ART运行时不像Dalvik虚拟机一样,马上就将它们标记对应的Space的Live Bitmap中去,而是将它们记录在Allocation Stack。这样做是为了可以执行Sticky Mark Sweep垃圾收集。 Heap类的成员函数FlushAllocStack首先调用另外一个成员函数MarkAllocStack将保存在Allocation Stack里面的对象标记到对应的Space的Live Bitmap去。注意,这时候Zygote进程只有三个Space,分别是Image Space、Zygote Space和Large Object Space。其中,Image Space是不能用来分配新对象的,因此,保存在Allocation Stack里面的对象要么是在Zygote Space上分配的,要么是Large Object Space上分配的。这时候就只需要将Zygote Space和Large Object Space的Live Bitmap取出来,连同Allocation Stack一起,传递给Heap类的成员函数MarkAllocStack,记它进行相应的标记。

划分之前,我们首先明确,Heap类的成员变量alloc_space_指向的实际上就是Zygote Space,但是接下来我们要将它指向Allocation Space,因此就先把Heap类的成员变量alloc_space_保存在本地变量zygote_space中。从Zygote Space划分出一个Allocation Space的操作是通过调用DlMallocSpace类的成员函数CreateZygoteSpace来实现。DlMallocSpace类的成员函数CreateZygoteSpace返回来的是新划分出来的Allocation Space,因此这时候就将它保存在Heap类的成员变量alloc_space_中了。

当Zygote进程在fork第一个应用程序进程之前,会将已经使用了的那部分堆内存划分为一部分,还没有使用的堆内存划分为另外一部分。前者就称为Zygote堆,后者就称为Active堆。以后无论是Zygote进程,还是应用程序进程,当它们需要分配对象的时候,都在Active堆上进行。这样就可以使得Zygote堆尽可能少地被执行写操作,因而就可以减少执行写时拷贝的操作。在Zygote堆里面分配的对象其实主要就是Zygote进程在启动过程中预加载的类、资源和对象了。这意味着这些预加载的类、资源和对象可以在Zygote进程和应用程序进程中做到长期共享。这样既能减少拷贝操作,还能减少对内存的需求。

 mspace_: 和Dalvik虚拟机一样,ART运行时也是将Zygote Space和Allocation Space使用的匿名共享内存块封装成一个mspace对象,以便可以使用C库提供的内存管理接口来在上面分配和释放内存。

Dalvik虚拟机并不是直接管理这块匿名共享内存,而是将它封装成一个mspace,交给C库来管理。mspace是libc中的概念,我们可以通过libc提供的函数create_mspace_with_base创建一个mspace,然后再通过mspace_开头的函数管理该mspace。例如,我们可以通过mspace_malloc和mspace_bulk_free来在指定的mspace中分配和释放内存。实际上,我们在使用libc提供的函数malloc和free分配和释放内存时,也是在一个mspace进行的,只不过这个mspace是由libc默认创建的。

在Image Space上分配的对象对在Zygote Space和Allocation Space上分配的对象的引用的Mod Union Table,以及在Zygote Space上分配的对象对在Allocation Space上分配的对象的引用的Mod Union Table。前一个Mod Union Table使用ModUnionTableToZygoteAllocspace类来描述,后一个Mod Union Table使用ModUnionTableCardCache类来描述。


如果ART运行时启动时指定了-XX:IgnoreMaxFootprint选项,即Heap类的成员变量ignore_max_footprint_的值等于true,那么就需要调用Heap类的成员函数SetIdealFootprint将Heap类的成员变量max_allowed_footprint_的值设置为size_t类型的最大值,即不对堆的大小进行限制。同时也会将Heap类的成员变量concurrent_start_bytes_设置为成员变量max_allowed_footprint_的值,这意味着不会触发并行GC。

==================================================
-rw-r--r-- 1 mutian mutian 15749120 Apr  3 15:38 system@framework@boot.art
-rw-r--r-- 1 mutian mutian 81015552 Apr  3 15:38 system@framework@boot.oat


image space:
sizeof(image_header) = 140
uint64_t image_file_size = static_cast<uint64_t>(file->GetLength());
image_file_size = 15749120
image_header.GetImageSize() = 15566800
15749120 = Align(15566800, 4K) + 176k

mmap(0x6f7fc000, 15568896, 0x3, 0x2, 6, 0) of file '/data/dalvik-cache/arm64/system@framework@boot.art'
15568896 = Align(15566800, 4K)
mmap(0x0, 180224, 0x1, 0x2, 6, 15568896) of file '/data/dalvik-cache/arm64/system@framework@boot.art'
image bitmap 180224 = 176K

//create ContinuousSpaceBitmap, only 11M has 176k bitmap
accounting::ContinuousSpaceBitmap::CreateFromMemMap() 
name:imagespace /data/dalvik-cache/arm64/system@framework@boot.art live-bitmap 0, heap_capacity:11534336 = 11M
11534336 = 176K * 64 = 11M
heap_capacity:11534336=11M, bitmap_size:180224=176K


image space SpaceType:0 GcRetentionPolicy:0 bitmap_index:0

kSectionObjects  .Offset():0
image_header.GetImageSection(ImageHeader::kSectionObjects).End(): 11411720
kSectionArtFields  .Offset():11411720
image_header.GetImageSection(ImageHeader::kSectionArtFields).End(): 11970648
kSectionArtMethods  .Offset():11970648
image_header.GetImageSection(ImageHeader::kSectionArtMethods).End(): 15126080
kSectionInternedStrings  .Offset():15126080
image_header.GetImageSection(ImageHeader::kSectionInternedStrings).End(): 15566800
kSectionImageBitmap  .Offset():15568896
image_header.GetImageSection(ImageHeader::kSectionImageBitmap).End(): 15749120



-----------------------------------------
non_moving_space_mem_map:
non_moving_space_capacity:67108864 = 64M
requested_alloc_space_begin: address after boot.oat
non_moving_space_mem_map.reset(MemMap::MapAnonymous(space_name, requested_alloc_space_begin,
       non_moving_space_capacity, PROT_READ | PROT_WRITE, true, false, &error_str));

//absolute address = 300M
main_mem_map_1, main_mem_map_2
capacity_:536870912=512M
--------

non_moving_space_ = space::DlMallocSpace::CreateFromMemMap(non_moving_space_mem_map.release(),
    "zygote / non moving space", kDefaultStartingSize, initial_size, size, size, false);
DlMallocSpace* DlMallocSpace::CreateFromMemMap(MemMap* mem_map, const std::string& name,
                                               size_t starting_size, size_t initial_size,
                                               size_t growth_limit, size_t capacity,
                                               bool can_move_objects) {
kDefaultStartingSize:4096 = 4K
initial_size:8388608 = 8M
size = 64M
non_moving_space_ SpaceType:1 GcRetentionPolicy:1


main_space_:
CreateMainMallocSpace(main_mem_map_1.release(), initial_size, growth_limit_, capacity_);
initial_size:8388608=8M
growth_limit_:201326592=192M
capacity_ =512M
SpaceType:1 GcRetentionPolicy:1
live_bitmap_  mark_bitmap_


main_space_backup_: same as main_space_
main_space_backup_.reset(CreateMallocSpaceFromMemMap(main_mem_map_2.release(), initial_size,
                                             growth_limit_, capacity_, name, true));
SpaceType:1 GcRetentionPolicy:1
live_bitmap_  mark_bitmap_


large_object_space_:
large_object_space_ = space::FreeListSpace::Create("free list large object space", nullptr, capacity_);
capacity_:512M
SpaceType:4 GcRetentionPolicy:1

 

 

posted @ 2016-03-12 17:41  牧 天  阅读(1614)  评论(0编辑  收藏  举报