1、说一下JVM的主要组成部分,及其作用?
- 类加载器:将java代码 转换成 字节码;
- 运行时数据区:将 字节码 加载到内存中;
- 执行引擎:将字节码 翻译成 底层系统命令,再交给CPU执行;
- 本地库接口:
组件的作用:
首先通过 类加载器 将java代码转换成字节码,运行时数据区 再把字节码加载到内存中,而字节码文件只是JVM的一套指令集的规范,并不能直接交给底层操作系统去执行,因此需要特定的 命令解析器执行引擎,将字节码翻译成底层系统命令,再交给CPU执行,而这个过程中需要调用其他语言的 本地库接口来实现整个程序的功能。
2、说一下JVM运行时数据区(JVM内存)?
线程私有:随着线程的创建而创建,随着线程的结束而释放,无需特定的内存管理
- 程序计数器:用来指示执行那条指令,多线程中通过线程切换分时复用CPU,所以每个线程都需要记录自己所需执行的指令
- 虚拟机栈(Java栈):栈中存放一个一个的栈帧,每一个栈帧存放一个被调用的方法,栈:后进先出。
- 本地方法栈:同JAVA栈,只是存放的是本地方法。
线程共享:通过垃圾回收机制管理内存
- 堆:存放数组和对象本身。二者的引用都放在java栈中 (通过垃圾回收机制进行内存管理)
- 方法区:存储了每个类的信息,静态变量,常量,以及编译后的代码;使用元空间来替换了永久代。存储类信息,编译后代码数据等应移存到元空间中。
3、说一下堆栈的区别?
栈内存 | 堆内存 | |
存储内容 | 局部变量 | 实体 |
更新速度 | 由于局部变量生命周期短,所以更新速度快 | 由于实体的生命周期长,更新速度慢 |
内存管理方式 | 内存随着生命周期结束而释放 | 通过来及回收机制不定时回收 |
4、什么是双亲委派模型?
双亲委派模型是应用于类加载器的、对任意一个类都需要 加载它的类加载器 和 这个类本身 一同确认在JVM中的唯一性。
双亲委派模型就是,当一个类加载器收到了加载类的请求,他首先不会自己去加载这个类,而是将这个请求委派给父类加载器去完成。每一层类加载器都如此,这样所有的加载请求都会传送到顶层的启动类加载器中,只有当父类无法完成加载请求,子加载类才会尝试去加载类。
5、说一下类加载的过程?
- 加载:将class字节码加载到内存中,并将这些数据转换成方法区中的运行时数据,在内存中生成一个Class类对象代表这个类(反射原理),作为方法区类数据的访问入口。
- 检查:检查加载的class类的正确性,确保加载的类的信息符合JVM规范,没有安全方面的问题;
- 准备:给类中的静态变量(static变量)分配内存空间,并设置变量的初始值,这里只是赋默认值,真正的赋值在初始化阶段;
- 解析:虚拟机将常量池中的符号引用替换成直接引用的过程。符号引用就是一个标识,直接引用就是指向内存中的地址。
- 初始化:完成变量的具体赋值
初始化的顺序:
- 父类的静态变量
- 父类的静态代码块
- 子类的静态变量
- 子类的静态代码块
实例化的顺序:
- 父类的非静态变量
- 父类的非静态代码块
- 父类的构造方法
- 子类的非静态变量
- 子类的非静态代码块
- 子类的构造方法
6、怎么判断对象是否可以被回收?
- 引用计数器:每个对象建立一个引用计数器,有对象引用,计数器 +1,引用被释放的时候计数器 -1,当计数器等于0的时候,就可以被回收了。存在无法解决循环应用的问题的缺点。
- 可达性算法:通过选取GC Root,与GC Root没有任何引用关系的对象,就会被回收。(问题:单例模式是怎么保证不被回收的)
7、java中有哪些引用类型?
- 强引用:new一个对象就是强引用,JVM内存不足的时候宁愿抛出OutOfMemoryError终止程序,也不会回收掉存活着的强引用对象
- 软引用:软引用的生命周期比强引用短一些,是通过SoftReference类实现的。软引用的对象会在JVM认为内存不足的时候才会对其进行回收,也就是会在抛出OutOfMemoryError之前进行回收。适用于在内存空闲时候保留缓存,在内存不足的时候就清理掉缓存,例如 图片缓存等。
Object obj = new Object(); //new 出来的对象就是强引用
SoftReference softObject = new SoftReference(obj);
obj = null; // 去除强引用
还可以结合ReferenceQueue一起使用,当softObject软引用的obj被回收了以后,softObject对象会被放进队列中。之后可以通过poll()产看你所关心的对象是否被回收掉,回收掉了就返回null,反之返回softObject的软引用。
Object obj = new Object(); //new 出来的对象就是强引用
ReferenceQueue queue = new ReferenceQueue();
SoftReference softObject = new SoftReference(obj,queue);
obj = null; // 去除强引用
- 弱引用:通过WeakReference类实现的,垃圾回收的时候,无论内存是否充足,都会回收掉该对象。ThreadLoda中的key使用的就是弱引用
Object obj = new Object(); //new 出来的对象就是强引用
WeakReference weakObject = new WeakReference(obj);
obj = null; // 去除强引用
- 虚引用:通过PhantomReference类实现的,必须配合ReferenceQueue来使用。任何时候都会被回收掉,就像没有引用一样。主要是用来跟踪对象的垃圾回收的活动。
8、说一下JVM有哪些垃圾回收算法
- 标记-清除算法
- 标记-整理算法
- 复制算法
- 分代回收算法
9、说一下JVM有哪些垃圾回收器?
11、详细介绍一下CMS垃圾回收器?
12、新生代垃圾回收期和老年代垃圾回收器都有哪些?有什么区别?
13、简述分代回收器是怎么工作的? 详情
14、说一下JVM调优工具?
JDK 自带了很多监控工具,都位于JDK的bin目录下,其中常用的是jconsole和jvisualvm这两个款视图监控工具。
-
jconsole:用于对 JVM 中的内存、线程和类等进行监控;
-
jvisualvm:JDK 自带的全能分析工具,可以分析:内存快照、线程快照、程序死锁、监控内存的变化、gc 变化等。
15、常用的JVM调优的参数有哪些?
-
-Xms2g:初始化推大小为 2g;
-
-Xmx2g:堆最大内存为 2g;
-
-XX:NewRatio=4:设置年轻的和老年代的内存比例为 1:4;
-
-XX:SurvivorRatio=8:设置新生代 Eden 和 Survivor 比例为 8:2;
-
–XX:+UseParNewGC:指定使用 ParNew + Serial Old 垃圾回收器组合;
-
-XX:+UseParallelOldGC:指定使用 ParNew + ParNew Old 垃圾回收器组合;
-
-XX:+UseConcMarkSweepGC:指定使用 CMS + Serial Old 垃圾回收器组合;
-
-XX:+PrintGC:开启打印 gc 信息;
-
-XX:+PrintGCDetails:打印 gc 详细信息。