【Android面试周】快问快答之Java篇
  • 类的加载篇
  • 垃圾回收机制篇
  • JVM篇
  • 多线程篇
  • 数据结构篇
  • ...

I. 类的加载篇

MyClass o = new MyClass() 背后发生了什么?【类的加载、链接、初始化】

  1. 首先ClassLoader会基于类的全限定名,将.class文件加载到JVM中,这个加载过程是基于双亲委托方式;
  2. 加载了 .class 后,当然要对它进行校验,确保它符合JVM规范;然后分配内存,如static变量,此时静态变量为默认值;
  3. 一切就绪后,就可以进行初始化了,执行它的构造函数和static代码,初始化刚刚分配好但未赋值的静态变量。

什么场合会触发类的初始化?

JVM规定了以下几种场合必须立即对类进行初始化

  1. 通过new、反序列化机制时;
  2. 调用类的static方法/使用类的static变量时;
  3. 通过反射调用类方法;
  4. 初始化该类的子类时(初始化子类必须先初始化父类);
  5. JVM标记的启动类(可以理解为具备main方法的类)。

简单说下 双亲委托 机制

首先,Java里有下面四种ClassLoader:

  • 启动类加载器 BootstrapClassLoader:C++实现,无法在Java里获取其引用,用于加载基础jar文件给JVM
  • 扩展类加载器 ExtClassLoader:加载扩展类如String
  • 应用程序类加载器 SystemClassLoader(AppClassLoader):加载用户创建的类
  • 自定义ClassLoader

所谓的 双亲委托,就是在加载一个类时,ClassLoader会先委托父级ClassLoader先去加载,只有当父级ClassLoader加载不到,才自己去加载。

上面四种加载器的加载顺序:BootstrapClassLoader > ExtClassLoader > SystemClassLoader > 自定义ClassLoader。

为什么要采用 双亲委托 机制

  1. 保证类的安全加载,防止冒充包名手动篡改核心类,如String类只能由ExtClassLoader加载;
  2. 不同类加载的相同全限定名的类,不是同一个类。

深入文章

《Java 技术之类加载机制》


II. 垃圾回收篇

有哪些垃圾回收算法?

  1. 标记-清理:对堆内存进行遍历,标记出其中无GC-Root引用的内存块进行标记,然后全部进行清理。这种方式会导致内存碎片;
  2. 标记-整理:同上,不过在清理后,将所有使用对象整理到一起,消除内存碎片,适用于“垃圾少,存活多”的场景;
  3. 复制:将堆内存分成A, B两块,使用时只用一块如A,当A填满了,进行一次gc,把A中存活对象复制到B,同时清空A,适用于“垃圾多,存活少”的场景

Java里的垃圾回收具体如何实现?

  1. Java里的堆分成了两部分:新生代、老年代;
top Created with Sketch.