Android虚拟机原理面试题汇总(含详细解析 二)

Android并发编程高级面试题汇总最全最细面试题讲解持续更新中👊👊
👀你想要的面试题这里都有👀
👇👇👇

Java对象会不会分配到栈中?

这道题想考察什么?

创建的对象是否都在堆中,如果不是,对照JVM运行时数据区堆栈相关内容,能够把控对象不在堆中对程序的影响

考察的知识点

逃逸分析

考生应该如何回答

Java对象可能会分配到栈中。

逃逸分析

逃逸分析指的是分析对象动态作用域,当一个对象在方法中定义后,它可能被外部方法所引用。比如:调用参数传递到其他方法中,这种称之为方法逃逸。甚至还有可能被外部线程访问到,例如:赋值给其他线程中访问的变量,这个称之为线程逃逸。从不逃逸到方法逃逸到线程逃逸,称之为对象由低到高的不同逃逸程度。

如果确定一个对象不会逃逸出线程之外,那么让对象在栈上分配内存可以提高JVM的效率。如果是逃逸分析出来的对象可以在栈上分配的话,那么该对象的生命周期就跟随线程了,就不需要垃圾回收,如果是频繁的调用此方法则可以得到很大的性能提高。

逃逸分析的触发前提条件必须触发JIT执行

public class EscapeAnalysisTest{
    public static void main(String[] args){
        long start = System.currentTimeMillis();
        for (int i = 0; i < 50000000; i++){
            allocate();
        }
        System.out.println((System.currentTimeMillis() - start) + " ms");
    }
    static void allocate(){
        Object obj = new Object();
    }
}

在上述代码中,Object对象属于不可逃逸,JVM可以做栈上分配。在启动JVM时候,通过 -XX:-DoEscapeAnalysis 参数可以关闭逃逸分析(JVM默认开启)。

开启逃逸分析:

在这里插入图片描述

关闭逃逸分析:
在这里插入图片描述

测试结果可见,开启逃逸分析对代码的执行性能有很大的影响!


GC的流程是怎么样的?介绍下GC回收机制与分代回收策略

这道题想考察什么?

Java基础掌握情况,掌握对象回收过程以避免开发时出现内存问题

考察的知识点

GC机制

考生如何回答

说到GC垃圾回收,首先要知道什么是“垃圾”,垃圾就是没有用的对象,那么怎样判定一个对象是不是垃圾(能不能被回收)?Java 虚拟机中使用一种叫作可达性分析的算法来决定对象是否可以被回收。

可达性分析

可达性分析就通过一组名为”GC Root"的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,最后通过判断对象的引用链是否可达来决定对象是否可以被回收。

在这里插入图片描述

GC Root指的是:

  • Java 虚拟机栈(局部变量表)中的引用的对象。也就是正在运行的方法中的局部变量所引用的对象
  • 方法区中静态引用指向的对象。也就是类中的static修饰的变量所引用的对象
  • 方法区中常量引用的对象。
  • 仍处于存活状态中的线程对象。
  • Native 方法中 JNI 引用的对象。
优点

可达性分析可以解决引用计数器所不能解决的循环引用问题。即便对象a和b相互引用,只要从GC Roots出发无法到达a或者b,那么可达性分析便不会将它们加入存活对象合集之中。

缺点

在多线程环境下,其他线程可能会更新已经访问过的对象中的引用,从而造成误报(将引用设置为null)或者漏报(将引用设置为未被访问过的对象)。误报并没有什么伤害,Java虚拟机至多损失了部分垃圾回收的机会。漏报则比较麻烦,因为垃圾回收器可能回收事实上仍被引用的对象内存。 一旦从原引用访问已经被回收了的对象,则很有可能会直接导致Java虚拟机崩溃。

垃圾回收算法

在标记出对象是否可被回收后,接下来就需要对可回收对象进行回收。基本的回收算法有:标记-清理、标记-整理与复制算法。

标记清除算法

从”GC Roots”集合开始,将内存整个遍历一次,保留所有可以被 GC Roots 直接或间接引用到的对象,而剩下的对象都当作垃圾对待并回收,过程分为 标记清除 两个步骤。

在这里插入图片描述

  • 优点:实现简单,不需要将对象进行移动。
  • 缺点:这个算法需要中断进程内其他组件的执行(stop the world),并且可能产生内存碎片,提高了垃圾回收的频率。
标记整理算法

与标记-清除不同的是它并不简单地清理未标记的对象,而是将所有的存活对象压缩到内存的一端。最后,清理边界外所有的空间。

  • 优点:这种方法既避免了碎片的产生,又不需要两块相同的内存空间,因此,其性价比比较高。
  • 缺点:所谓压缩操作,仍需要进行局部对象移动,所以一定程度上还是降低了效率。
复制算法

将现有的内存空间分为两快,每次只使用其中一块,在垃圾回收时将正在使用的内存中的存活对象复制到未被使用的内存块中。之后,清除正在使用的内存块中的所有对象,交换两个内存的角色,完成垃圾回收。

在这里插入图片描述

  • 优点:按顺序分配内存即可,实现简单、运行高效,不用考虑内存碎片。
  • 缺点:可用的内存大小缩小为原来的一半,对象存活率高时会频繁进行复制。
分代回收策略

不同的垃圾收集器实现采用不同的算法进行垃圾回收,除此之外现代虚拟机还会采用分代机制来进行垃圾回收,根据对象存活的周期不同,把堆内存划分为不同区域,不同区域采用不同算法进行垃圾回收。

分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的。因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率。

在Java程序运行的过程中,会产生大量的对象,其中有些对象是与业务信息相关,比如Http请求中的Session对象、线程、Socket连接,这类对象跟业务直接挂钩,因此生命周期比较长。但是还有一些对象,主要是程序运行过程中生成的临时变量,这些对象生命周期会比较短,比如:String对象,由于其不变类的特性,系统会产生大量的这些对象,有些对象甚至只用一次即可回收。

试想,在不进行对象存活时间区分的情况下,每次垃圾回收都是对整个堆空间进行回收,花费时间相对会长,同时,因为每次回收都需要遍历所有存活对象,但实际上,对于生命周期长的对象而言,这种遍历是没有效果的,因为可能进行了很多次遍历,但是他们依旧存在。因此,分代垃圾回收采用分治的思想,进行代的划分,把不同生命周期的对象放在不同代上,不同代上采用最适合它的垃圾回收方式进行回收。

代际划分

在这里插入图片描述

堆内存分为年轻代(Young Generation)和老年代(Old Generation)。而持久代使用非堆内存,主要用于存储一些类的元数据,常量池,java类,静态文件等信息。

垃圾回收

年轻代会划分出Eden区域与两个大小对等的Survivor区域。 其比例一般为8:1:1,这是因为根据统计95%的对象朝生夕死,存活时间极短。

  1. 新生成的对象优先存放在新生代中
  2. 存活率很低,回收效率很高
  3. 一般采用的 GC 回收算法是复制算法

当新对象生成,并且在Eden申请空间失败时,就会触发GC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区,然后整理Survivor的两个区。这种方式的GC是对年轻代的Eden区进行,不会影响到年老代。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。所以一般在这里需要使用速度快、效率高的算法,使Eden区能尽快空闲出来。

minor gc

新对象的内存分配都是先在Eden区域中进行的,当Eden区域的空间不足于分配新对象时,就会触发年轻代上的垃圾回收,我们称之为"minor gc"。同时,每个对象都有一个“年龄”,这个年龄实际上指的就是该对象经历过的minor gc的次数。如图1所示,当对象刚分配到Eden区域时,对象的年龄为“0”,当minor gc被触发后,所有存活的对象(仍然可达对象)会被拷贝到其中一个Survivor区域,同时年龄增长为“1”。并清除整个Eden内存区域中的非可达对象。

当第二次minor gc被触发时,JVM会通过Mark算法找出所有在Eden内存区域和Survivor1内存区域存活的对象,并将他们拷贝到新的Survivor2内存区域(这也就是为什么需要两个大小一样的Survivor区域的原因),同时对象的年龄加1. 最后,清除所有在Eden内存区域和Survivor1内存区域的非可达对象。

当对象的年龄足够大(年龄可以通过JVM参数进行指定,默认为15岁,CMS收集器默认6岁,不同的垃圾收集器会略微有点不同 ),当minor gc再次发生时,它会从Survivor内存区域中升级到年老代中,如图3所示。

major gc

当minor gc发生时,又有对象从Survivor区域升级到Tenured区域,但是Tenured区域已经没有空间容纳新的对象了,那么这个时候就会触发年老代上的垃圾回收,我们称之为"major gc"。而在年老代上选择的垃圾回收算法则取决于JVM上采用的是什么垃圾回收器。

总结

在JVM中一般采用可达性分析法进行是否可回收的判定,确定对象需要被回收后,对象在哪个代际将会采用不同的垃圾回收算法进行回收,这些算法包括:标记-清除,标记-整理与复制算法。

而之所以采用分代策略的原因是:不同的对象的生命周期是不一样的。因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率。 如果每次垃圾回收都是对整个堆空间进行回收,花费时间相对会长,而对于生命周期长的对象而言,这种遍历是没有效果的,因为可能进行了很多次遍历,但是他们依旧存在。

由于面试题内容比较多,篇幅有限,资料已经被整理成了PDF文档,有需要2023年Android中高级最全面试真题答案 完整文档的可扫描下方卡片免费获取~

PS:(文末还有使用ChatGPT机器人小福利哦!!大家不要错过)

目录

在这里插入图片描述

第一章 Java方面

●Java基础部分
●Java集合
●Java多线程
●Java虚拟机

在这里插入图片描述

第二章 Android方面

●Android四大组件相关
●Android异步任务和消息机制
●Android UI绘制相关
●Android性能调优相关
●Android中的IPC
●Android系统SDK相关
●第三方框架分析
●综合技术
●数据结构方面
●设计模式
●计算机网络方面
●Kotlin方面

在这里插入图片描述

第三章 音视频开发高频面试题

●为什么巨大的原始视频可以编码成很小的视频呢?这其中的技术是什么呢?
●怎么做到直播秒开优化?
●直方图在图像处理里面最重要的作用是什么?
●数字图像滤波有哪些方法?
●图像可以提取的特征有哪些?
●衡量图像重建好坏的标准有哪些?怎样计算?

在这里插入图片描述

第四章 Flutter高频面试题

●Dart部分
●Flutter部分

在这里插入图片描述

第五章 算法高频面试题

●如何高效寻找素数
●如何运用二分查找算法
●如何高效解决雨水问题
●如何去除有序数组的重复元素
●如何高效进行模幂运算
●如何寻找最长回文子串

在这里插入图片描述

第六章 Andrio Framework方面

●系统启动流程面试题解析
●Binder面试题解析
●Handler面试题解析
●AMS面试题解析

在这里插入图片描述

第七章 企业常见174道面试题

●SD卡
●Android的数据存储方式
●Broadcast Receiver
●sp频繁操作会有什么后果?sp能存多少数据?
●dvm与jvm的区别
●ART
●Activity的生命周期
●Application能不能启动Activity
●…

在这里插入图片描述

搭建了一个基于chatGPT的微信群聊机器人,24小时为大家解答疑难技术问题, 需要的可以扫描二维码进群。

图片

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值