jvm java虚拟机相关面试题

jvm内存区域

  1. 程序计数器
    当前线程执行字节码的行号,线程私有
  2. jvm 栈
    线程私有,用来描述方法执行的,分为局部变量表、操作数栈、动态链接、方法出口存,局部变量表是放基本数据类型、String、和对象引用,方法执行会创建栈帧,方法嵌套层数过多会抛出StackOverFlow异常,如果jvm无法申请到足够的栈空间会报OOM

  3. 堆用来存储对象,是线程共享的区域,会发生OOM
  4. 方法区
    存储类信息,静态变量,常量

类加载

过程
加载-验证-准备-解析-初始化-使用-卸载
加载:

  1. 通过类的全名获取到二进制字节流(实际就是读文件)
  2. 将字节流转换成方法区中的动态数据结构
  3. 在堆中生成class对象

准备:

  1. 为类变量分配内存并设置初始值,但是实例变量不会。
  2. 设置初始值是数据类型对应的默认值,并非代码中值;
    比如
public static int var = 1;

在初始阶段var的是0 不是1,赋值成1是在初始化阶段

初始化:
顺序:(父类静态变量>父类静态代码块)>(子类静态变量>子类静态代码块)>(父类变量>父类初始化块)>(父类构造方法)>(子类变量>子类初始化块)>(子类构造方法)
触发条件:

  • new 对象
  • 使用静态变量、静态方法
  • 反射(classforName(xxx))
  • 执行main方法
  • 初始化子类会先初始化父类

类加载器

  • Bootstrap Classloader 最顶层类加载器,加载java_home/lib路径下jar包和class文件
  • Extention Classloader 拓展类加载器,加载java_hoe/lib/ext 路径下jar包和class文件
  • Appication Classloader 应用类加载器
  • 自定义类加载器 实现AppicationClassloader
    • 两种方式

(1)遵守双亲委派模型:继承ClassLoader,重写findClass()方法。

(2)破坏双亲委派模型:继承ClassLoader,重写loadClass()方法。 通常我们推荐采用第一种方法自定义类加载器,最大程度上的遵守双亲委派模型。

  • 步骤
    (1)创建一个类继承ClassLoader抽象类
    (2)重写findClass()方法
    (3)在findClass()方法中调用defineClass()

双亲委派模型

类加载器收到类加载的请求后会先委托给父类去加载,所有请求都会传到Bootstrap ClassLoader,只有父类加载不到的才会自己执行。
好处:避免重复加载、安全

内存分配

  • Edion
    • 新创建的对象优先放到Edion
  • 老年代
    • 大对象直接进入老年代(好处是能减少Minor GC)
    • Survivor中多次存活的对象进入老年代
    • Minor GC后新生代存活的对象大于Survivor空间的一半 存储到老年代

垃圾回收

  • Minor GC条件
    当Edion不足以创建对象时
  • Full GC
    当Minor GC后需要进入到老年代对象大于老年代剩余空间

垃圾回收算法

  1. 引用计数器算法
  2. 标记清除算法
  3. 标记整理算法
  4. 复制算法
  5. 分代收集算法

垃圾收集器

发布了6 篇原创文章 · 获赞 3 · 访问量 863

猜你喜欢

转载自blog.csdn.net/weixin_40882266/article/details/104984339