[面试准备]虚拟机

122 阅读6分钟

名称解释

  • 操作数:线程执行的方法内的局部变量称为操作数
  • 操作码:线程执行的方法称为操作码
  • 局部变量表:包含了对应的方法参数和局部变量
  • 字面量:可以理解为字面意思的常量。比如,字符串字面量:"abc";整型字面量:123。比如:int a = 123; a是变量,123是字面量
  • 符号引用:可以是任意类型的字面量。只要能无歧义的定位到目标。在编译期间由于暂时不知道类的直接引用,因此先使用符号引用代替。最终还是会转换为直接引用访问目标。
  • 直接引用:就是直接指向地址值的引用,就是内存地址。

JVM内存模型

  1. JVM运行时内存区域划分

参考:jvm虚拟机架构

运行时内存区域 * 栈(线程不共享) * 虚拟机栈:保存局部变量表、操作数和方法出口等。 * 本地方法栈 * 程序计数器 * 堆(线程共享) * 堆(新生代、老年代): * 方法区(PermGen-永久代):

  1. 栈主要存的数据是什么,堆呢?

    • 栈主要描述的是方法执行的内存语义,主要保存的是:局部变量信息、方法出口、操作数、动态链接等。

    • 堆分为堆和非堆,非堆即方法区(meta space),方法区保存了虚拟机加载的类信息、常量、静态变量、即时编译后的代码。

  2. 方法区保存了哪些数据
    class文件
    常量池
    类的静态变量
    即时编译后的代码

  3. 常量池保存了哪些数据

    1. 类的符号引用
    2. 字符串常量池

    彻底弄懂java常量池
    java总结之基础类型与常量池

  4. 堆分为哪几块,比如说新生代老年代,那么新生代又分为什么? 从垃圾回收角度来说分为新生代和老年代。
    新生代:Eden、from survior、to survior,默认是8:1:1,eden是对象的出生区,survior是minor gc之后幸存的对象。
    老年代:存放大对象;生存超过15次的对象;survior空间中年龄相等的对象超过一半。

  5. 分配内存空间的方法

    • 指针碰撞:指针移动,寻找空闲区块(适合内存规整的方式)
    • 空闲列表:虚拟机记录空闲区块的列表,选择合适的空间(利用率高,需要维护成本)
  6. 虚拟机如何解决分配内存的线程安全问题 修改指针的时候线程安全问题

    • 采用CAS配上失败重试,保证更新操作的原子性
    • TLAB 本地线程分配缓冲区 每个线程在堆中预先分配一小块内存,哪个线程需要分配内存,就在哪个线程的TLAB上分配,只有TLAB用完,并且需要分配新的内存的时候,才需要同步锁定。
  7. 虚拟机中对象的创建过程

    虚拟机中对象的创建过程

  8. Java在什么时候会出现内存泄漏(Memory Leak)、内存溢出(Memory Overflow);

    Java 内存泄漏与内存溢出详解

    • 内存泄露:在申请了内存之后,没有释放(对java来说无法回收)导致可用内存空间越来越小。
    • 内存溢出:申请了10空间,但是实际使用11空间。
  9. Java中的大对象如何进行存储;

    • 通过jvm设置,可以指定大对象直接进入老年代
    • 如何优化:拆分、合并、压缩
  10. JVM7、8详解及优化 blog.csdn.net/u013980127/…

  11. 对象实例在内存中的结构 对象头: 对象头又分为:MarkWord、指向类的指针、数组长度 实例数据: 对其填充字节:

JVM调试

  1. 常见的JVM性能监控和故障处理工具类:jps、jstat、jmap、jinfo、jconsole等 blog.csdn.net/xad70734812…

  2. 几种常用的内存调试工具:jmap、jstack、jconsole;

  3. 内存溢出OOM和堆栈溢出SOE的示例及原因、如何排查与解决

  4. JVM如何设置参数 -Xms 最小堆内存 -Xmx 最大堆内存 -Xmn 新生代内存大小 -Xss 栈内存容量 -PermSize 方法区最小 -MaxPermSize 方法区最大 -XX:NewSize和-XX:MaxNewSize 用于设置年轻代的大小,建议设为整个堆大小的1/3或者1/4,两个值设为一样大。 -XX:SurvivorRatio 用于设置Eden和其中一个Survivor的比值,这个值也比较重要。

  5. JVM性能调优

垃圾回收机制

  1. 哪些内存需要回收(对象存活判断算法)

    1. 引用计数法,对象内记录被引用的次数,当次数归0时即可被回收。 缺点: 循环引用的问题无法解决
    2. 可达性分析算法
      1. 是否从根节点可达
      2. 根节点有哪些:
        1. 虚拟机栈中的引用的对象
        2. 类的静态变量和final修饰的常量
        3. 本地方法栈引用的对象
  2. 强引用、软引用、弱引用、虚引用 为了更灵活的处理引用,java定义了不同的级别的引用。

    • 强引用:不会被回收
    • 软引用:当内存空间不够的时候,会被回收
    • 弱引用:肯定会被回收
    • 虚引用:虚引用是否存在对对象完全没有影响,使用虚引用完全是为了在这个对象被回收的时候收到系统通知。
  3. 软引用和弱引用的使用场景

  4. Minor GC与Full GC分别在什么时候发生?什么时候触发Full GC; blog.csdn.net/chenleixing…

    何时full gc 1、老年代空间不足 2、永久代空间不足 3、System.gc 4、minor gc 空间不足,需要进入老年代的时候,如果老年代的空间不足以担保

  5. 为什么新生代内存需要有两个Survivor区? 使用复制算法用,比例Eden 8,survior 1(from) 1(to)

  6. 常见的GC回收算法及其优劣

    • 标记-清除
    • 标记-整理
    • 复制
  7. GC收集器有哪些?CMS收集器与G1收集器的特点。

  8. G1停顿吗,CMS回收步骤,CMS为什么会停顿,停顿时间;

编译器

类增强

类加载模型

  1. 类加载器的工作原理

  2. 一个类的生命周期、类是如何加载到JVM中的

  3. 类加载的五个过程:加载、验证、准备、解析、初始化;

  4. 什么是双亲委派模型

  5. 怎么打破双亲委派模型,为什么要打破

  6. JDBC和双亲委派模型关系

  7. 类加载器的并发加载问题 利用synchronized blog.csdn.net/w1673492580…

  8. rt.jar被什么类加载器加载,什么时间加载;

  9. 自己写的类被什么加载,什么时间加载;

  10. 自己写的两个不同的类是被同一个类加载器加载的吗?为什么?

  11. 符号引用、直接引用、接口引用 (blog.csdn.net/imzoer/arti…

问题列表

  1. zhuanlan.zhihu.com/p/67160781
  2. zhuanlan.zhihu.com/p/103234051

参考文章

jvm虚拟机架构 深入理解JVM之JVM内存区域与内存分配 类加载器总结 自定义类加载器 内存管理与垃圾回收 静态变量、全量变量和局部变量