码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • Android基础第八天 | 字节跳动第四届青训营笔记


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

    打开ART虚拟机的大门

    文章目录

      • 打开ART虚拟机的大门
        • 课程回顾
        • 课程背景
          • ART 演进
          • ART整体架构
        • 01 对象篇
          • 1.1 对象的生命之旅
          • 1.2 类管理
            • 1.2.1 决定一个对象的大小和行为
            • 1.2.2 基类Object的秘密
            • 1.2.3 类加载
            • 1.2.4 内存布局
            • 1.2.5 双亲继承
            • 1.2.6 合理的继承抽象的好处
          • 1.3 内存分配
            • 1.3.1 分配器
            • 1.3.2 不同的分配器的特点
            • 1.3.3 一些典型的场景
            • 1.3.4 内存碎片
          • 1.4 内存回收
            • 1.4.1 两种思路
            • 1.4.2 RC的问题和解决
            • 1.4.3 ART的引用
            • 1.4.4 触发GC的条件
            • 1.4.5 苹果手机内存少的原因之一
            • 1.4.6 GC的方式
            • 1.4.7 tracing GC
            • 1.4.8 copying GC
            • 1.4.9 ART的做法
            • 1.4.10 回收之后
        • 02 执行篇
          • 2.1 虚拟机的执行方式
            • 2.1.1 虚拟机的执行方式 - JIT
            • 2.1.2 虚拟机的执行方式 - OAT
            • 2.1.3 虚拟机的执行方式 - 延迟绑定
          • 2.2 栈管理
            • 2.2.1 不同执行方式之间的切换
            • 2.2.2 简单总结
          • 2.3 异常处理
          • 2.4多线程
            • 2.4.1 多线程 —— synchronize
          • 2.5 同步机制 —— monitor
            • 2.5.1 胖锁和瘦锁
            • 2.5.2 同步机制 —— 胖瘦锁切换

    课程回顾

    为什么做性能优化、性能优化是什么、如何做性能优化、最佳性能工具选型

    课程背景

    ART 演进

    在这里插入图片描述

    ART整体架构

    在这里插入图片描述

    01 对象篇

    1.1 对象的生命之旅

    在这里插入图片描述

    1.2 类管理

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

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

    内存布局:类成员的大小,类型,和排布

    函数信息:主要是虚表的信息:某个函数定义在当前类函数表的第几个位置。因为java是支持继承的,因此类的内存布局和函数虚表需要做继承链全展开以后才能真正确认。(这也是动态性的来源)

    1.2.2 基类Object的秘密

    java Object基类源码

    在这里插入图片描述

    在这里插入图片描述

    1.2.3 类加载

    一个类分配的对象大小,是由继承链决定的

    JAVA的类,是在第一次使用的时候,才会进行加载

    1.2.4 内存布局

    在这里插入图片描述

    1.2.5 双亲继承

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

    1.2.6 合理的继承抽象的好处

    合理的抽象,不是图方便直接塞在顶层基类上,这就是“优雅的架构”带来的现实的好处

    1.3 内存分配

    1.3.1 分配器

    APP的java对象内存分配上是托管到VM来处理的,并不会直接向操作系统去申请,实际上对OS内存的占用和内存布局,是VM控制的(预留-扩展)

    1.3.2 不同的分配器的特点

    在这里插入图片描述

    1.3.3 一些典型的场景

    在这里插入图片描述

    1.3.4 内存碎片

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

    在这里插入图片描述

    1.4 内存回收

    1.4.1 两种思路

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

    RC:引用计数(Reference Counting),指的是对一个对象引用进行计数,多一个引用者,就+1,少一个就-1,为0就释放。典型的如IOS的swift就使用RC进行内存管理

    1.4.2 RC的问题和解决

    在这里插入图片描述

    1.4.3 ART的引用

    在这里插入图片描述

    1.4.4 触发GC的条件

    1.我们想要不被预期外的GC导致卡顿,可以考虑适当的预留内存

    2.大小有上限可预期的情况,new一个大数组,可能比分配一大堆放到容器里面要好。

    1.4.5 苹果手机内存少的原因之一

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

    因为GC触发总归是有条件的并且触发会导致卡顿,所以不可能无时无刻都保持清理,必然每个应用都会维持一个垃圾堆,应用多了,积累的垃圾量就很大了

    1.4.6 GC的方式

    GC roots的概念:怎么判断哪些内存是有用的那些是没用的?

    1.4.7 tracing GC

    从roots遍历,所有mark的对象是有holder的,释放掉没有holder的object

    在这里插入图片描述

    1.4.8 copying GC

    从roots遍历,把有用的的对象拷贝到另一个区域,然后集中释放掉当前区域的内存

    在这里插入图片描述

    1.4.9 ART的做法

    在这里插入图片描述

    1.4.10 回收之后

    finalize方法一般用来跟随对象的生命周期,清理掉绑定的native资源

    一个对象的finalize方法只会执行一次,再次激活之后的对象是不会触发finalize的。

    02 执行篇

    2.1 虚拟机的执行方式

    在这里插入图片描述

    2.1.1 虚拟机的执行方式 - JIT

    在这里插入图片描述

    2.1.2 虚拟机的执行方式 - OAT

    OAT(或者AOT),和川T不同,是在程序运行之前,对APK中的函数进行编译。

    1.和程序是否运行无关

    2.编译的范围不是以函数为单位,而是以dex为单位的。

    3.结果会持久化。

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

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

    绑定的越早,动态性越差,性能越好

    2.2 栈管理

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

    1.对于解释执行,栈托管到虚拟机完成。

    2对于编译后的,压栈处理和native代码是一样的,遵从对应指令集的约定

    2.2.1 不同执行方式之间的切换

    对于AOTJIT到解释执行,或者反之的调用,ART采用trampoline-bridge机制来进行切换

    2.2.2 简单总结

    1.压栈-出栈的速度不同,解释执行的速度慢

    2.解释执行的栈结构是托管的,编译执行的栈结构是遵从虚拟机规则的

    3.解释执行传递参数有额外的空间成本,编译执行没有

    4.不同执行方式之间调用切换采用trampoline/bridge进行

    2.3 异常处理

    当拿到一个异常的时候,会逐级的回栈,做两个事情:

    1.回一级栈看看要不要
    2.如果不要就跳出

    2.4多线程

    多线程必然带来原子性问题,那ART怎么解决的呢?

    在这里插入图片描述

    2.4.1 多线程 —— synchronize

    JAVA引入了sync机制,让我们加锁解锁很方便

    2.5 同步机制 —— monitor

    回到Oject基类的结构中,此时我们就知道,shadow monitor是干嘛用的了,如果我们对一个
    对象使用了sync,这个对象就会生成一个lock,保留在这个shadow monitor指向的内存地址中

    2.5.1 胖锁和瘦锁

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

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

    2.5.2 同步机制 —— 胖瘦锁切换

    在这里插入图片描述

  • 相关阅读:
    进程间通信
    openGauss学习笔记-65 openGauss 数据库管理-创建和管理数据库
    不同linux 比较
    网络入门基础
    关于用pygame来编写类满天星游戏的全记录
    npmjs官网(查询依赖包)
    机械臂速成小指南(十八):圆弧规划
    1106 2019数列分数 15
    789. 数的范围
    『期末复习』16/32位微处理器(8086)基本寄存器
  • 原文地址:https://blog.csdn.net/weixin_44226181/article/details/126316626
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号