张三求职日记--面试题篇--JVM

23 阅读3分钟

张三求职日记--面试题篇--JVM封面图.jpg

JVM内存模型

  1. 堆:主要用于存放new出的对象和数组,可通过GC回收。
  2. 虚拟机栈:线程私有栈,存着栈帧,主要是局部变量表,也就是基本数据类型和对象引用等信息。
  3. 本地方法栈:用于存放Native方法。
  4. 程序计数器:用于标识程序执行的字节码指令地址,线程私有。
  5. 方法区(非堆):主要存储类的信息、常量池、静态变量等。
    java7之前叫永久代,java8之后改为了元空间,使用本地内存,理论上无上限,但一般使用时需要指定元空间大小。

类加载流程

通常分为7个流程:加载、验证、准备、解析、初始化、使用、卸载。

  1. 加载:通过类名获取二进制字节流,将字节流转换为方法区的运行时数据结构,生成class对象作为访问入口。由类加载器完成加载。
  2. 验证:检查字节码合法性。
  3. 准备:为静态变量分配内存并附默认值。
  4. 解析:将符号引用替换为直接引用。
  5. 初始化:执行clinit方法,按顺序初始化静态变量和静态代码块。
  6. 使用:类完成初始化后进入运行阶段,可被实例化或调用方法。
  7. 卸载:当类无实例、引用且类加载器被回收时,JVM卸载该类。

服务中用到的JVM参数(常见)

  1. -Xms、-Xmx:用于配置初始堆大小和最大堆大小。
  2. XX:MetaspaceSize=32m -XX:MaxMetaspaceSize=256m:用于控制初始元空间大小和最大元空间大小。
  3. -XX:+HeapDumpOnOutOfMemoryError:用于使服务出现OOM异常后生成dump文件。
  4. XX:NewRatio:用于配置新生代老年代比例。

垃圾收集器

Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1、ZGC。

垃圾回收算法

标记-清除:内存碎片较多,很少使用。 复制:一般新生代使用。 标记-整理:一般老年代使用。 分代收集:典型代表CMS收集器,G1收集器的分区粒度更细。

类加载器

  1. 启动类加载器(BootStrap ClassLoader):加载如rt包下面的类。
  2. 扩展类加载器(Extension ClassLoader):加载如javax包下面的类。
  3. 应用类加载器(Application ClassLoader):加载classpath下的类。
  4. 自定义加载器(Customize ClassLoader):自定义类继承ClassLoader重写findClass方法加载类。 JDK9之后扩展类加载器变成了平台类加载器(Platform ClassLoader)。

双亲委派机制

一个类加载器加载某个类的时候,会优先委派父加载器处理,父加载器不能完成加载时自己才会进行加载。可保障核心类库的安全性。

如何破坏双亲委派机制

双亲委派机制历史上有三次破坏。

  1. 自定义加载器重写loadClass方法,跳过父类委托。
  2. 通过SPI机制进行破坏。
  3. 通过OSGi模块化加载。

如何定位OOM问题