Java面试——JVM(1)

Java的类加载

  • 过程
    • 加载过程
      • 类的二进制流 –> 运行时数据结构 –> 生成一个Class对象作为这个类各种数据的访问入口
    • 验证
      • 确保Class文件符合虚拟机要求
    • 准备
      • 类变量分配内存空间,设置零值
    • 解析阶段
      • 将常量池中的符号引用替换为直接引用的过程
      • 符号引用
        • 通俗的说可以认为是类的全路径
      • 直接引用
        • 可以是指针、相对偏移量、句柄等可以定位到目标的量
    • 初始化
      • 执行真正的初始化工作

类加载器

  • 分类
    • Java的类加载器
    • OSGI
  • 类与类加载器是一一对应的关系,同一类经过不同加载器加载就是不同的类
  • 双亲委托模型
    • 涉及的角色
      • 启动类加载器、扩展类加载器、应用类加载器、自定义类加载器
    • 工作过程
      • 请求都会委派给父类加载器,当父加载器反馈无法加载时,子加载器才会去加载
    • 优缺点
      • 优点是不会产生重复加载问题
      • 缺点是当基础类需要调回用户代码时,会产生问题,灵活性不够
        • Java设计团队解决方案是引入上下文类加载器

Minor GC 与 Full GC

  • Minor GC 新生代
    • 一般采用复制算法,效率比较高; 通过两个S区来配合进行垃圾回收
    • 触发条件,当Eden区内存使用到达一定限度时,就会进行垃圾回收
    • Hotspot方案为每次使用一块大的Eden和其中一块S区,当回收时,就将Eden区 和使用的S区中存活的放入到另一个S区,然后清理使用过的S区和Eden区,当S区空间不足时就会触发空间分配担保
  • Full GC 老年代
  • 一般采用标记整理算法
  • 触发条件,老年代空间使用到达一定限度时,或者新生代的空间分配担保失败时(有参数,可以冒险也可以不冒险,不冒险时就会触发)

内存分配与回收策略

  • 优先在新生代进行分配
  • 大对象直接进入老年代(所以尽量避免短命大对象,容易导致提前触发垃圾收集)
  • 长期存活的对象将进入老年代,默认年龄是15岁(当移入S区时年龄设置为1,每经历一次MinorGC年龄就增加一岁)
  • 动态年龄判定——当相同年龄的对象大小总和大于S区大小的一半时
  • 空间分配担保
    • 堆空间够晋升的对象分
    • 不够的话再判断历届晋升的平均大小

Full GC频繁发现?解决方案

  • 使用 jstat -gcutil pid 进行查看
  • 或者使用jconsole 可视化工具也可以看出来
  • 解决方案
    • 需要根据具体的场景,分析各个区的占用情况来总和分析
    • 可能的原因一个是因为空间分配担保失败

你可能感兴趣的:(Java,Java面试)