类加载的生命周期?

加载、验证、准备、解析、初始化五个阶段

类加载器的层次?

image.png
启动类加载器: Bootstrap ClassLoader
扩展类加载器: Extension ClassLoader
应用程序类加载器: Application ClassLoader
自定义类加载器: 因为JVM自带的ClassLoader

Class.forName()和ClassLoader.loadClass()区别?

  • Class.forName(): 将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块;
  • ClassLoader.loadClass(): 只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。
  • Class.forName(name, initialize, loader)带参函数也可控制是否加载static块。并且只有调用了newInstance()方法采用调用构造函数,创建类的对象

JVM类加载机制有哪些?

  1. 全盘负责
  2. 父类委托
  3. 缓存机制
  4. 双亲委派机制

如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上,因此,所有的类加载请求最终都应该被传递到顶层的启动类加载器中,只有当父加载器在它的搜索范围中没有找到所需的类时,即无法完成该加载,子加载器才会尝试自己去加载该类。

这样好处,是避免应用层改写String同名类,而导致jdk自身的类被替换掉,有了双亲委派,则可以避免这个问题,所有类都由最顶级的启动器类加载器来加载;

内存结构

线程私有:程序计数器、虚拟机栈、本地方法栈
线程共享:堆、方法区, 堆外内存(Java7的永久代或JDK8的元空间、代码缓存)

栈帧的内部结构?

  • 局部变量表(Local Variables)
  • 操作数栈(Operand Stack)(或称为表达式栈)
  • 动态链接(Dynamic Linking):指向运行时常量池的方法引用
  • 方法返回地址(Return Address):方法正常退出或异常退出的地址

堆区内存是怎么细分的?

年轻代 (Young Generation) Minor GC
伊甸园 Eden Memory 默认比例是8:1:1
两个幸存区 from/to或s0/s1
老年代(Old Generation) Major GC

image.png

对象有哪些引用类型?

  1. 强引用 被强引用关联的对象不会被回收。
  2. 软引用 被软引用关联的对象只有在内存不够的情况下才会被回收。
  3. 弱引用 被弱引用关联的对象一定会被回收,也就是说它只能存活到下一次垃圾回收发生之前。
  4. 虚引用 又称为幽灵引用或者幻影引用。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用取得一个对象。

有哪些基本的垃圾回收算法?

标记 - 清除
标记 - 整理
复制
分代收集

如何判断一个对象是否可以回收?

引用计数算法
可达性分析算法

垃圾回收种类

  • 新生代收集(Minor GC/Young GC):只是新生代的垃圾收集
  • 老年代收集(Major GC/Old GC):只是老年代的垃圾收集
    • 目前,只有 CMS GC 会有单独收集老年代的行为
    • 很多时候 Major GC 会和 Full GC 混合使用,需要具体分辨是老年代回收还是整堆回收
  • 混合收集(Mixed GC):收集整个新生代以及部分老年代的垃圾收集
    • 目前只有 G1 GC 会有这种行为
  • 整堆收集(Full GC):收集整个 Java 堆和方法区的垃圾 调用 System.gc(),老年代空间不足