ART虚拟机入门 | 青训营笔记

124 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第19天

ART虚拟机

ART整体架构

微信图片_20220813150643.png

对象篇

  • 对象是谁 -- 类的管理
  • 对象从哪里来 -- 内存分配
  • 对象到哪里去 -- 内存回收 9bf48f5115b7169a86d7ea9330a0d31.png

对象的生命旅程

对象分配

  • 分配多大 -- 类
    • 类主要描述的是一个对象的内存布局和函数信息
    • 内存布局:类成员的大小、类型、排布
    • 函数信息:虚表的信息:某个函数定义在当前函数表的第几个位置,由于java支持继承,因此类的内存布局和函数虚表需要做继承链全展开后才能真正确认(这也是动态性的来源)
  • 怎么分配 -- 内存管理
    • APP的java对象内存分配上是托管到VM来处理的,并不会直接向操作系统去申请,实际上对OS内存的占用和内存布局由VM控制(预留-扩展)
    • 分配方式
      • TLAB:临时变量(小量内存)
      • ROSallocator:数组/容器(中等内存)
      • LOSallocator:bitmap储存图片(大量内存) 7d46b55c863e470081c1c04f72d4cc3.png
    • 内存碎片:多次分配后内存被分割成多个小块

对象销毁(内存回收)

  • GC(垃圾回收):定期查找系统内不用的对象,并且释放占用的内存

    • 触发条件:
      • 没内存了
      • 手机认为该GC了:VM堆达到占用水位、系统内存紧张、经济性策略
    • GC判断方式:
      • 主要思路:不能被释放:栈、static变量、native ref、VM保留
      • tracing GC:从roots遍历,所有mark的对象是由holder的,释放没有holder的object
      • copying GC:从roots遍历,把有用的对象拷贝到另一个区域,然后集中释放之前区域的内存(好处:得到的内存空间是连续的)
  • RC(引用计数):对一个对象引用进行技术,多一个引用者就+1,少一个就-1,为0时释放

  • 引用的等级

    • 强引用:直接持有
    • 软引用:内存不够时就会回收
    • 弱引用:只要触发GC就会被回收

执行篇

  • 搬砖的姿势 -- 虚拟机的执行方式

    • 解释执行:dex code
    • JIT:解释执行时给每一个函数生成一个profile文件,每次执行此函数会打分,分够了就提交给JIT编译器,JIT编译器编译后执行OST替换,下一次执行就用JIT执行而不是解释执行
    • OAT(AOT):与JIT的不同之处:
      • OAT在程序运行前对APK中的函数进行编译
      • 编译范围不是以函数为单位,而是以dex为单位
      • AOT的产物会持久化
  • 开始和结束 -- 栈管理

    • ART对于解释执行和编译后指令采取两种不同的策略:
      1. 对于解释执行的,栈托管到虚拟机完成
      2. 对于编译后的,压栈处理和native代码是一样的,遵从对应指令集的约定
  • 高效的执行 -- 多线程

    • Object类中有shadow monitor成员,当对一个对象使用了sync是,此对象会生成一个lock指针保存在shadow monitor指向的内存地址中

    • 胖锁和瘦锁:ART有这两种锁,monitor一开始会生成瘦锁

      • 瘦锁:不断地轮询对方好了没 -- 费劲但响应快,实际上采用spinlock
      • 胖锁:完成了再通知锁 -- 省力但反应慢,实际上采用mutelock
      • 一开始是瘦锁,当发现等待时间太多了就会转成胖锁