打开ART虚拟机的大门 | 青训营笔记

102 阅读4分钟

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

打开ART虚拟机的大门

本堂课内容

  1. 对象
    1. 对象是谁——类的管理
    2. 对象从哪里来——内存分配
    3. 对象到哪里去——内存分配
  2. 执行
    1. 虚拟机的执行方式
    2. 栈管理
    3. 多线程

知识点介绍

对象

对象的生命历程

  1. 对象分配(分配多大类、怎么分配?)
  2. 对象使用(执行类的方法、访问对象成员)
  3. 对象销毁(内存回收)

类管理

这是决定一个对象的大小和行为

类主要描述的是一个对象的内存布局和函数信息

通过查看java源码,可以看出Object基类的定义:

public class Object{
	private transient Class<?> shadow$__klass_;
	private transient int shadow$_monitor_;
}

类加载

一个类分配的对象大小,是由继承链决定的,JAVA的类是在第一次使用的时候才会进行加载

双亲继承

本质上,双亲委派就是一个认为划定的一个规矩,目的是为了保证系统内同一个类的一致性

抽象继承的好处

合理的抽象,会让定义对象属性的时候变得更加优雅

内存分配

APP的java对象内存分配上是托管到虚拟机来处理的,并不会直接向操作系统去申请,实际上对OS内存的占用和内存布局是虚拟机来决定的

内存分配的一些典型场景

少量的内存使用便捷,但是内存的量小;大块的内存使用时候需要从大池子里面取,使用的时候比较慢

ART的内存分配的根本原理,还是给使用者在最优的范围内找到一块大小符合的连续内存

内存碎片

我们在使用内存的时候希望的是可用内存尽可能的连续起来,在回收内存后尽量少的产生内存碎片

内存回收

  1. GC:垃圾回收,需要顶起查找系统内不用的对象,并且释放占用的内存
  2. RC:引用计数,指的是对一个对象引用进行计数,多一个引用者就+1,少一个就-1,为0就释放

ART的引用

强引用就是引用,是直接持有的

软引用是内存不够的时候会回收

弱引用是只要出发GC就会被回收

触发GC的条件

  1. 没内存的时候就会触发GC

  2. 系统判断到应该GC了,就会触发GC

    场景有:VM堆占用达到水准,系统内存紧张,想触发了

IOS使用的内存少的原因

同样是三个APP,IOS的每个app内存空间里面都是只有在用内存,不存在浪费

GC的判断方式

怎么判断哪些内存是有用的,哪些是没用的;

从roots遍历,所有mark的对象是有holder的,最后再释放掉没有holder的object,这种方式叫做tracing GC

从roots遍历,把有用的对象拷贝到另一个区域,然后集中释放的掉当前区域中的内存空间,这种方式叫做copying GC

ART的做法

前台GC后台GC
使用场景应用在前台的进程非前台应用进程
算法trancing GCcopying GC
速度
内存碎片
额外空间不需要需要

执行

执行方式

  1. 解释执行——dex code
  2. JIT——JIT code
  3. AOT——AOT code

JIT的OSR就是栈上替换,在某些分支可以采用更激进的优化,处理不了还能回退

OAT

与JIT不同的是,在程序运行之前,对APK中的函数进行编译

  1. 和程序是否运行无关
  2. 编译的范围不是以函数为单位的,而是以dex为单位的
  3. 结果会持久化

虚拟机的执行方式——延迟绑定

绑定的越迟——动态性越好,性能越差

绑定过越早——动态性越差,性能越好

栈管理

ART对于解释执行和编译后指令采用两种不同的策略

  1. 对于解释执行,栈托管到虚拟机完成
  2. 对于编译后的,压栈处理和native代码一样,遵循指令集的约定

异常处理

发生异常现象的时候也会产生回栈的现象

多线程和同步

java引入了sync机制,让加锁和解锁变得很方便

瘦锁费劲但是响应快,实现上采用spinlock

胖锁省力但是反应慢,实现上采用mutexlock

个人总结

本章简单的了解了的有关ART虚拟机的相关知识,由于涉及到许多虚拟化以及操作系统的知识,感觉对于这部分的理解是在不是很透彻,需要课下结合老师推荐的两本数目慢慢的消化消化