安卓面试必备的JVM虚拟机制详解,看完之后简历上多一个技能( 四 )
G1 收集器的运作过程大致可划分为以下四个步骤:
1.初始标记
仅仅只是标记一下 GC Roots 能直接关联到的对象 , 这个阶段需要停顿线程 , 但耗时很短 。
2.并发标记
从 GC Root 开始对堆中对象进行可达性分析 , 递归扫描整个堆里的对象图 , 找出要回收的对象 , 这阶段耗时较长 , 但是可与用户程序并发执行 。
3.最终标记
对用户线程做另一个短暂的暂停 , 用于处理在并发标记阶段新产生的对象引用链变化 。
4.筛选回收
负责更新 Region 的统计数据 , 对各个 Region 的回收价值和成本进行排序 , 根据用户所期望的停顿时间来制定回收计划 。
G1 的目标是在可控的停顿时间内完成垃圾回收 , 所以进行了分区设计 , 但是 G1 也存在一些问题 , 比如停顿时间过长 , 通常 G1 的停顿时间在几十到几百毫秒之间 , 虽然这个数字其实已经非常小了 , 但是在用户体验有较高要求的情况下还是不能满足实际需求 , 而且 G1 支持的内存空间有限 , 不适用于超大内存的系统 , 特别是在内存容量高于 100GB 的系统上 , 会因内存过大而导致停顿时间增长 。
ZGC 在 JDK11 被引入 , 作为新一代的垃圾回收器 , 在设计之初就定义了三大目标:支持 TB 级内存 , 停顿时间控制在 10ms 之内 , 对程序吞吐量影响小于 15% 。
类加载机制虚拟机把描述类的数据从 Class 文件加载到内存 , 并对数据进行校验、解析和初始化 , 最终形成可以被虚拟机直接使用的 Java 对象 , 这就是虚拟机的类加载机制 。
类加载流程分为五个阶段 , 分别是加载、验证、准备、解析和初始化 。
加载阶段 , 就是通过一个类的全限定名来获取定义此类的二进制字节流 , 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构 。 加载阶段是开发人员可控性最强的阶段 , 因为开发人员可以自定义类加载器 。 对于数组而言 , 情况有所不同 , 数组类本身不通过类加载器创建 , 它是由 Java 虚拟机直接创建 。
验证是链接阶段的第一步 , 这一阶段的目的是为了确保 Class 文件的字节流中包含的信息符合当前虚拟机的要求 , 并且不会危害虚拟机自身的安全 。 它包括文件格式校验、元数据校验、字节码校验等 。
准备阶段是正式为类变量分配内存并设置类变量初始值的阶段 , 这些变量所使用的内存都将在方法区中进行分配 。 需要注意的是 , 这时候进行内存分配的仅仅包含类变量 , 不包括实例变量 , 实例变量将会在对象实例化时随着对象一起分配在 Java 堆上 。 其次 , 这里所说的变量初始值是该数据类型的零值 。
解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程 。 符号引用以一组符号来描述所引用的目标 , 直接引用可以是直接指向目标的指针 。
初始化阶段是执行类构造器 () 方法的过程 。 () 方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块中的语句合并产生的 , 编译器收集的顺序是由语句在源文件中出现的顺序所决定的 。 虚拟机会保证一个类的 () 方法在多线程环境中被正确的加锁同步 , 如果多个线程同时去初始化一个类 , 那么只会有一个线程去执行这个类的 () 方法 , 其他线程都需要阻塞等待 , 这也是静态内部类能实现单例的主要原因之一 。
文章插图
双亲委派模型【安卓面试必备的JVM虚拟机制详解,看完之后简历上多一个技能】双亲委派模型的工作过程是:如果一个类加载器收到类加载的请求 , 它首先不会自己去尝试加载这个类 , 而是把这个请求委派给父类加载器去完成 , 每一层次的类加载器都是如此 , 因此所有的类加载请求最终都应该传送给顶层的启动类加载器中 , 只有当父类加载器反馈自己无法完成这个加载请求时 , 子加载器才会尝试自己去加载 。
推荐阅读
- 为什么苹果用户哪怕买二手机,都不用安卓?三点原因太真实
- 华为老机喜迎第二春:从安卓6.0直升10.0
- 手机看片就用它!百万大片免费看,支持苹果安卓,还支持iPad
- Win10 真的要兼容安卓 App 了,微软到底想玩什么
- NVIDIA Broadcast体验 主播必备30系显卡
- 华为突然全面下架腾讯游戏“国内安卓渠道分成矛盾由来已久”
- VIVO最薄5G手机 随拍安卓旗舰手机VIVO X60
- 小米11必备!小米55W充电器开始预约:仅99元
- 仿效苹果取消充电器,小米11搭载全球安卓最强芯片,继续冲击高端
- 小米发布MIUI12.5全新系统 凌驾安卓媲美iOS