这两种看了下art虚拟机的内存分配原理,在这儿简要的共享一下。 在art虚拟机里,保护了很多个空间分配内存,这些内存空间在art的源码里边被抽象成一个个Space方针。类之间的联系我从网上找了一下张图来表明,十分清晰:

ART虚拟机内存分配原理浅析

Space依据内存空间是否接连分为两类:

  • ContinuousSpace 内存空间接连,这儿首要代表有两种
    • ImageSpace 这表明的是系统镜像的内存空间,咱们一般重视不到
    • CntinuiusMemMapAllocSpace的几个子类,这些Space都是一些不同的内存分配战略,对应的则是虚拟机不同的GC战略。依据文档和一些网上能够查到的资料,咱们一般也就联系 RegionSpace 和 MallocSpace。
  • DisContinuousSpace 内存空间不接连,首要代表便是 LargeObejctSpace(大方针)

小方针分配

小方针分配会依据咱们的GC收回算法来指定咱们的分配战略。详细的一个对应联系能够参阅我整理的这个图:

ART虚拟机内存分配原理浅析
在AndroidO之后,Android默许指定的垃圾收回算法是CC(并发仿制)算法,在CC之前规则为,前台运用的是 CMS(并发符号铲除),后台运用的空间紧缩算法。 所以对咱们来说,首要关怀的便是两种:

  • KCollectorTypeCMS
  • KCollectorTypeCC

这2个gc的算法核心还是仿制算法和符号铲除算法,同时支持了和程序并发运行。我找了两张图,回忆一下这两种算法:

  1. 仿制算法

仿制算法在收回内存空间的时分,收回器会把内存分为巨细持平的两部分,在gc发生的时分,会把存活的方针从源空间仿制到方针空间,仿制完毕后,一切的存活方针都排布在方针空间。然后把源空间悉数铲除。这是一个典型的空间换时间的战略。

ART虚拟机内存分配原理浅析

  1. 符号铲除算法

符号铲除算法便是符号出需求收回的方针,符号完成之后一致进行收回。符号铲除的缺陷便是内存碎片空间会变多,在之后分配内存的时分简略在方针接连内存空间不行的时分触发频频gc。

ART虚拟机内存分配原理浅析

回忆完 CMS 和CC,咱们持续看相关的分配战略,这儿别离对应了:

  • KAllocatorTypeRegionTLAB、KAllocatorTypeRegion
    • 这儿依据是否支持TLAB来决定,实测证明现在手机用的 KAllocatorTypeRegionTLAB,这个是高版别Android默许的小方针分配战略。
  • KAllocatorTypeRosAlloc、KAllocatorTypeDlMalloc
    • DlMalloc实际上内存分配便是用的C言语的malloc,在art虚拟机里,Google替换成了自己的 ROS (runs-of-slots) 算法,所以现在大部分运用场景是 ROS的
RegionAlloc

在heap的TryToAllocate函数里边,判别到 RegionAlloc:

ART虚拟机内存分配原理浅析
ART虚拟机内存分配原理浅析
别离看下Region和RegionTLAB:
ART虚拟机内存分配原理浅析
这段代码还比较好了解,把内存分成了一个一个Region,经过Region去分配对应的内存。每个Region有固定的巨细(kRegionSize(256kb))。当一个Region分配方针不行,咱们就先分配一个Region出来。 经过Region分配方针内存,核心代码便是下图圈出来的部分,用top指针保护当前分配到哪里:
ART虚拟机内存分配原理浅析
当方针分配的内存需求大于1个Region的时分,会按Region分配里的LargeObject去处理(需求注意这儿的大方针和largeObjectSpace的大方针不是一回事),LargeObject处理比较复杂,大概意思便是经过创建多个Region去分配,详细这儿不深入研究。 RegionAllocTLAB则是每个线程会分配一个空间,假如tlab分配失利则会按照RegionAlloc的方法去分配
ART虚拟机内存分配原理浅析
TLAB便是每个线程自己的内存区域,这个和java里的ThreaLocal应该是同一种思想。减少内存竞赛,进步内存分配的功率。

RosAlloc

RosAlloc便是一个魔改版别的malloc,RosAlloc保护了一个Slot链表,每个Slot叫做Run,每个Slot有自己的内存size,能够灵敏分配。这个算法的长处便是内存分配精确,能减少碎片化,缺陷则是需求不适合分配大方针。关于RosAlloc的代码我就不分析了,感觉没什么必要,网上随意找个过程的图:

ART虚拟机内存分配原理浅析
ART虚拟机内存分配原理浅析

大方针分配

除了一般小方针,还有一个很重要的方针分配空间便是大方针了。

ART虚拟机内存分配原理浅析
当满意大方针分配条件的时分会走 AllocLargeObject 逻辑。
ART虚拟机内存分配原理浅析
当分配字节数大于阈值,并且分配方针是根本类型数组或许字符串,那就符合大方针的条件。 阈值是kMinLargeObjectThreshold,即3页巨细,每页是4096,也便是4k。所以说一个根底类型数组或许字符串大于 12k,就归于大方针了,就会分配到 LargeObjectSpace 里边。
ART虚拟机内存分配原理浅析

LargeObjectSpace有两种实现,别离是 FreeListSpace和 LargeObejctMapSpace:

ART虚拟机内存分配原理浅析
ART虚拟机内存分配原理浅析
ART虚拟机内存分配原理浅析
这儿看的话,假如手机cpu架构是arm64的,运用的是FreeListSpace,否则是 LargeObejctMapSpace。 详细分配逻辑在他们各自的 Alloc 函数里:

  • LargeObjectMapSpace

ART虚拟机内存分配原理浅析
直接运用mmap匿名映射一块内存。

  • FreeListSpace

FreeListSpace则是在初始化内存空间的时分,直接mmap了必定size的内存运用,然后给内存空间分页,这些页被保护在一个链表里边,内存分配的时分会先去查找有无地址和巨细相同的空间,有就会复用,没有的话就会拓荒新的页去进行分配。

ART虚拟机内存分配原理浅析
这儿的size代码里边追溯一下能够追溯到 Heap 的 growth_limit, 也便是虚拟机参数 -XX:HeapGrowthLimit=_:
ART虚拟机内存分配原理浅析
这儿能够了解成: 在arm64架构的设备上,LargeObejctSpace分配内存的最大约束和使用进程的最大堆内存一致。 在非arm64架构的设备上,LargeObejctSpace内存分配没有指定的约束巨细。

总结

简略总结了一下art虚拟机内存分配的原理,经过这些点咱们能够对安卓里这些java方针如何分配有一个简略的认知,对排查内存相关问题,研究一些内存性能优化方案树立一个根底。