JVM面试题
内存模型
:各个部分的作用,保存哪儿些数据
类加载
:双亲委派加载机制,常用加载器分别加载哪儿种类型的类
GC
:分带回收的思想依据
性能调优
:JVM工具,性能分析工具
执行模式
:解释模式,编译模式,混合模式等
编译器优化
:javac的变异过程
JVM内存模型
线程私有:栈,本地方法栈,程序计数器
1 2 3 4 5 6 7 8 9 10 11 12
| 栈 又称方法栈,线程私有的,线程执行方法是都会创建一个栈帧, 用来存储局部变量表、操作栈、动态链接、方法出口等信息。 调用方法时执行入栈,方法返回时执行出栈
本地方法栈 与栈类似,也是用来保存执行方法的信息, 执行Java方法是使用占,执行Native方法时是使用本地方法栈
程序计数器 保存当前线程执行的字节码位置,每个线程工作时都有独立的计数器, 值为执行Java方法服务,执行Native方法时,程序计数器为空
|
线程共享:堆,方法区
1 2 3 4 5 6 7 8 9 10 11
| 堆 JVM内存管理最大的一块,堆被线程共享,目的是存放对象的实例,几乎所有对象的实例都会放在这里。 当堆没有可用空间时,会抛出OOM异常(Out of Menory内存溢出),根据对象的存活周期不同, JVM把对象进行分代管理,由垃圾回收器进行垃圾的回收管理 新生代内存(Young Generation) 老生代(Old Generation) 永久代(Permanent Generation)、1.8版本:元空间
方法区 又称非堆区,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器优化后的代码等数据 1.7的永久代和1.8的源空间都是方法区的一种实现
|
类的加载和卸载
1 2 3 4 5 6 7 8 9
| 加载:通过类的全限定名,查找此类的字节码文件,利用字节码文件创建Class对象
链接:分为三个阶段 验证:确保Class文件符合当前虚拟机的要求,不会危害到虚拟机自身安全 准备:进行内存分配,为static修饰的类变量分配内存,并设置初始值(0或null), 不包含final修饰的静态变量,因为final变量在编译时就分配好了 解析:将常量池中的符号引用替换为直接引用的过程,直接引用为直接指向目标的指针或者相对偏移量等 初始化:主要完成静态块执行以及静态变量的复制,先初始化父类,再初始化当前类。 初始化是懒惰的,只有对类主动使用的时候才会初始化
|
加载机制:双亲委派机制
1 2 3 4
| 加载机制:双亲委派模式 当一个类加载器收到类加载请求时,它首先会将这个请求委托给父类加载器去处理。 如果父类加载器无法加载该类,则该类加载器才会自己去加载这个类。 优点:避免类的重复加载,避免Java的核心API被篡改
|
卸载过程
1 2
| 类卸载的实现依赖于JVM的垃圾回收机制。当一个类不再被引用时 JVM可能会通过垃圾回收机制将该类的实例回收
|
对象的创建过程
1 2 3 4 5 6 7 8 9
| Java对象的创建过程可以概括为以下几个步骤
类加载:JVM会先检查类是否已经被加载了,如果没有则通过类加载器加载类的class文件,并将类的信息存储到方法区中 内存分配:当类被加载后,JVM会为该类的对象分配内存,根据Java对象的特点, 内存大小是在编译时就已经确定的,因此内存分配可以通过一些简单的算法来实现,例如指针碰撞和空闲列表等 初始化:内存分配完成后,JVM会对对象进行默认初始化,即将对象的成员变量赋上默认值。 基本类型的默认值是0或false,引用类型的默认值是null 构造函数:默认初始化后,JVM会调用该对象的构造函数,进行对象的属性初始化和一些其他操作 返回地址:构造函数执行完毕后,JVM会将对象的引用返回给调用者,此时对象创建过程完毕
|
JVM中的垃圾回收机制,大致说一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| GC是JVM的垃圾回收机制 首先GC有多种算法: 标记清除:遍历整个堆,清除所有未标记的对象,将其内存空间释放。 标记压缩:将所有存活的对象压缩到堆的一端,保持连续的内存空间,清除端释放未使用的空间。 复制算法:将堆内存分成两部分,活动对象从一个区域复制到另一个区域,不活动的对象直接丢弃 (新生代) 堆内存区域划分: 新生代,老年代,元空间 GC的过程: minor GC:年轻代满的时候发生,主要复制算法 Full GC:老年代空间不够用的时候 垃圾收集器 JVM 提供了多种垃圾收集器,不同收集器适用于不同的应用场景:
Serial 收集器:适用于单线程环境,简单高效。 Parallel 收集器:适用于多线程环境,采用并行的方式进行垃圾回收。 CMS(Concurrent Mark-Sweep)收集器:适用于低停顿时间的应用,主要用于老年代的垃圾回收。 G1(Garbage First)收集器:适用于大内存和高吞吐量的应用,采用分区算法,能够并发和并行回收内存。
|
有看过GC日志吗
1 2 3 4 5
| 没看过 调用System.gc()方法后 在IDEA中的application配置那里 输入一个什么命令去查看 -Xlog:gc*:file=<path-to-log-file>:time,uptime:filecount=10,filesize=10M
|
如何判断一个对象是垃圾
1 2 3
| 1.没有被引用的指向时候 2,无法通过引用链到达的时候 3,没有重写finalize方法
|