Android常见面试题
Android虚拟机和java虚拟机的原理和区别1、虚拟机简述虚拟机即虚构模拟出来的计算机,它是通过软件模拟仿真的方式来实现各种实际计算机上的功能,它具有完善的架构,如处理器、堆栈、寄存器等,同样它也有自己的一套指令系统,即字节码中所使用的各个指令。2、Java虚拟机简述Java虚拟机是实现上述所有逻辑功能、支持运行Java字节码的一种虚拟机,可以把它理解为架在特定系统上的一层软件,一般由特定硬件
TCP的三次握手/四次挥手
Android虚拟机和java虚拟机的原理和区别
1、虚拟机简述
虚拟机即虚构模拟出来的计算机,它是通过软件模拟仿真的方式来实现各种实际计算机上的功能,它具有完善的架构,如处理器、堆栈、寄存器等,同样它也有自己的一套指令系统,即字节码中所使用的各个指令。
2、Java虚拟机简述
Java虚拟机是实现上述所有逻辑功能、支持运行Java字节码的一种虚拟机,可以把它理解为架在特定系统上的一层软件,一般由特定硬件架构的汇编语言、C/C++语言来实现。因此每一种系统平台的虚拟机底层实现都依赖于具体的操作系统和硬件架构,都需要专门的移植,以保证不同平台但相同的接口暴露、外部特性和执行结果一致性,从而实现Java程序的字节码的跨平台执行。
JVM,Java虚拟机,是运行java程序(字节码文件)的环境,具有跨平台性,要运行java程序,必须安装java程序所运行平台对应的虚拟机,.java文件是人编写的,给人看的。.class文件是通过工具处理.java文件后的产物,它是给JVM看的,给JVM操作的
3、Dalvik虚拟机简述
Dalvik虚拟机和Java虚拟机一样都是运行Java程序的虚拟机,它专门为嵌入式环境设计的,所以在系统资源有限的情况下也能够很好的工作,Google官方对Dalvik虚拟机的特点说明:
- 在一个设备上支持多个虚拟机进程
- 针对CPU高度优化的字节码解释器
- 非常高效的运行时内存使用
位于Android系统框架的倒数第二层的Android Runtime中,Dalvik虚拟机主要完成对象生命周期管理、堆栈管理、线程管理、安全和异常管理以及垃圾回收等重要功能;每一个Android应用在底层都会对应至少一个独立的Dalvik虚拟机实例,其代码在虚拟机的解释下得以执行。
Android应用虽然也是使用Java语言进行编程,但是在编译成CLASS文件后,还会通过一个工具(dx)将应用所有的 CLASS文件转换成一个DEX文件,而后Dalvik虚拟机会从其中读取指令和数据
Dalvik:应用每次运行的时候,字节码都需要通过即使编译器转化为机器码,这会拖慢应用运行的效率
ART:应用在第一次安装的时候,字节码就会预先编译成机器码,使其成为真正的本地应用,应用的启动和执行都会显著的提升
4、JVM和DVM的区别
虽然Dalvik也是一种Java虚拟机,但是它与普通的Java虚拟机不同,主要区别在以下几个方方面
垃圾回收
- Garbage Collection,垃圾收集,垃圾回收
- 强引用,软引用,弱引用,虚引用
- GC回收会阻塞主线程,可能会引发ANR,Android5.0之前GC回收线程是单线程,Android5.0之后GC回收线程是多线程并发回收
- 非静态的内部类与匿名类对它们外部的Class有强引用
- GC是按照有向图是否可达来判断对象实例是否有用
- 如果不再需要某个实例,却仍然被引用,这个情况叫做内存泄露
GC为了能够正确释放对象,会监控每个对象的运行状况,对他们的申请、引用、被引用、赋值等状况进行监控,Java会使用有向图的方法进行管理内存,实时监控对象是否可以达到,如果不可到达,则就将其回收,这样也可以消除引用循环的问题。
GC的工作原理
为了更好理解 GC 的工作原理,我们可以将对象考虑为有向图的顶点,将引用关系考虑为图的有向边,有向边从引用者指向被引对象。另外,每个线程对象可以作为一个图的起始顶点,例如大多程序从 main 进程开始执行,那么该图就是以 main 进程顶点开始的一棵根树。在这个有向图中,根顶点可达的对象都是有效对象,GC将不回收这些对象。如果某个对象 (连通子图)与这个根顶点不可达(注意,该图为有向图),那么我们认为这个(这些)对象不再被引用,可以被 GC 回收。 以下,我们举一个例子说明如何用有向图表示内存管理。对于程序的每一个时刻,我们都有一个有向图表示JVM的内存分配情况。以下右图,就是左边程序运行到第6行的示意图。
Java使用有向图的方式进行内存管理,可以消除引用循环的问题,例如有三个对象,相互引用,只要它们和根进程不可达的,那么GC也是可以回收它们的。这种方式的优点是管理内存的精度很高,但是效率较低。另外一种常用的内存管理技术是使用计数器,例如COM模型采用计数器方式管理构件,它与有向图相比,精度行低(很难处理循环引用的问题),但执行效率很高。
JVM GC垃圾回收机制
内存分配策略
Java 程序运行时的内存分配策略有三种,分别是静态分配,栈式分配,和堆式分配,对应的三种存储策略使用的内存空间主要分别是静态存储区,也称方法区,栈区和堆区
静态存储区
也叫方法区,主要存放静态数据、全局 static 数据和常量。这块内存在程序编译时就已经分配好,并且在程序整个运行期间都存在。栈区
当方法被执行时,方法体内的局部变量(其中包括基础数据类型、对象的引用)都在栈上创建,并在方法执行结束时这些局部变量所持有的内存将会自动被释放。因为栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
分配堆中对象或数组的引用变量堆区
又称动态内存分配,通常就是指在程序运行时直接 new 出来的内存,也就是对象的实例,数组。这部分内存在不使用时将会由 Java 垃圾回收器来负责回收。
内存管理
- 栈:对象的引用
- 堆:new出来的对象,数组
- 方法区:类信息、常量(常量池)、静态变量
Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池(Class文件常量池),用于存放编译器生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。
- 程序计数器
一块较小的内存空间,它是当前线程所执行的字节码的行号指示器,字节码解释器工作时通过改变该计数器的值来选择下一条需要执行的字节码指令,分支、跳转、循环等基础功能都要依赖它来实现。每条线程都有一个独立的的程序计数器,各线程间的计数器互不影响,因此该区域是线程私有的。
- 用有向图表示引用关系,可达,存在连接通路,不可达
- GC 为了能够正确释放对象,GC 必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC 都需要进行监控。
Java的内存管理就是对象的分配和释放问题。在 Java 中,程序员需要通过关键字 new 为每个对象申请内存空间 (基本类型除外),所有的对象都在堆 (Heap)中分配空间。另外,对象的释放是由 GC 决定和执行的。在 Java 中,内存的分配是由程序完成的,而内存的释放是由 GC 完成的,这种收支两条线的方法确实简化了程序员的工作。但同时,它也加重了JVM的工作。这也是 Java 程序运行速度较慢的原因之一。因为,GC 为了能够正确释放对象,GC 必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC 都需要进行监控。
监视对象状态是为了更加准确地、及时地释放对象,而释放对象的根本原则就是该对象不再被引用。
什么是ANR,如何避免它?
在Android 上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应(ANR:Application Not Responding)对话框。用户可以选择让程序继续运行,但是,他们在使用你的应用程序时,并不希望每次都要处理这个对话框。因此,在程序里对响应性能的设计很重要,这样,系统不会显示ANR 给用户
不同的组件发生ANR 的时间不一样,主线程(Activity、Service)是5 秒,BroadCastReceiver 是10 秒
解决方案
将所有耗时操作,比如访问网络,Socket 通信,查询大量SQL 语句,复杂逻辑计算等都放在子线程中去,然后通过handler.sendMessage、runonUITread、AsyncTask 等方式更新UI。无论如何都要确保用户界面操作的流畅度,如果耗时操作需要让用户等待,那么可以在界面上显示进度条
dvm 的进程和Linux 的进程, 应用程序的进程是否为同一个概念?
dvm 指dalvik 的虚拟机。每一个Android 应用程序都拥有一个独立的Dalvik 虚拟机实例,应用程序都在它自己的进程中运行。而每一个dvm 都是在Linux 中的一个进程,所以说可以近似认为是同一个概念。
什么是android DVM:Dalvik 是Google 公司自己设计用于Android 平台的Java 虚拟机,每一个Dalvik 应用作为一个独立的Linux 进程执行。独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭。
Dalvik 和Java 虚拟机的区别
Dalvik 主要是完成对象生命周期管理,堆栈管理,线程管理,安全和异常管理,以及垃圾回收等等重要功能。
Dalvik 负责进程隔离和线程管理,每一个Android 应用在底层都会对应一个独立的Dalvik 虚拟机实例,其代码在虚拟机的解释下得以执行。
不同于Java 虚拟机运行java 字节码,Dalvik 虚拟机运行的是其专有的文件格式Dex
dex 文件格式可以减少整体文件尺寸,提高I/O 操作的类查找速度。
odex 是为了在运行过程中进一步提高性能,对dex 文件的进一步优化。
所有的Android 应用的线程都对应一个Linux 线程,虚拟机因而可以更多的依赖操作系统的线程调度和管理机制
有一个特殊的虚拟机进程Zygote,他是虚拟机实例的孵化器。它在系统启动的时候就会产生,它会完成虚拟机的初始化,库的加载,预制类库和初始化的操作。如果系统需要一个新的虚拟机实例,它会迅速复制自身,以最快的数据提供给系统。对于一些只读的系统库,所有虚拟机实例都和Zygote 共享一块内存区域。
sp 频繁操作有什么后果?sp 能存多少数据?
Sp 的底层是由xml 来实现的,操作sp 的过程就是xml 的序列化和解析的过程。Xml 是存储在磁盘上的,因此考虑到需要I/O 速度问题,sp 不适宜频繁操作。同时序列化xml 是就是将内存中的数据写到xml 文件中,由于dvm 的内存是很有限的,因此单个sp 文件不建议太大,具体多大是没有一个具体的要求的,但是我们知道DVM 堆内存也就是16M,因此数据大小肯定不能超过这个数字的。其实sp 设置的目的就是为了保存用户的偏好和配置信息的,因此不要保存太多的数据
Android四大组件
View的绘制流程
事件分发机制
Handler原理
AsyncTask原理
源码分析
Animation
Android5.0/6.0/7.0新特性
MaterialDesign
高并发编程
安全加密
移动支付
性能优化
设计模式
屏幕适配
注解反射动态代理
动态加载技术
更多推荐
所有评论(0)