文章目录
- 1、JVM前言
- 2、JVM的位置
- 3、JVM体系架构图
- 4、类加载器ClassLoader
1、JVM前言
必须掌握的内容1、请你谈谈你对JVM的理解? java8 虚拟机有什么更新?
2、什么是OOM,请你说说OOM产生的原因?如何分析?
3、JVM 的常用调优参数有哪些?
4、内存快照抓取,如何分析,命令是什么?
5、堆里面分区:Eden、Survial(from to)、老年区
6、GC垃圾收集算法有那个几个?谈谈利弊?
进阶内容1、JVM 垃圾回收的时候如何确定垃圾,GC Roots?
2、-X、-XX 参数你用过哪些?
3、你常用的项目,发布后配置过JVM 调优参数吗?
4、引用、强引用、弱引用、虚引用都是什么,请你谈谈?
5、GC垃圾回收器和GC算法的关系?分别有哪些?
6、谈谈默认的垃圾回收器?
7、G1垃圾回收器的特点?
8、OOM 你看过几种?
2、JVM的位置
文章图片
3、JVM体系架构图
文章图片
- 一般我们所谓的JVM调优,其实主要是对堆(heap)的调整。
- 栈、程序计数器、本地方法栈中是不会有垃圾的。
文章图片
类的加载、链接、初始化
- 加载:查找并加载类的二进制数据
- 链接:
(1)验证:保证被加载类的正确性
(2)准备:给类的静态变量分配内存空间,赋值一个默认的初始值。
(3)解析:被类中的符号应用替换为直接应用(java编译为class文件时,虚拟机并不知道引用的所在地址,作了个标记“符号引用”。转为真正的引用,找到对应的直接地址) - 初始化:给静态变量赋正确的值
public class Test{
public static int a = 1;
}
// 1、加载编译文件为 .class 文件,通过类加载,加载到JVM// 2、连接
验证(1)保证Class类文件没有问题
准备(2)给int类型分配内存空间,a = 0;
解析(3)符号引用转换为直接引用// 3、初始化
经过这个阶段的解析,把1 赋值给 变量 a;
类加载static
package com.coding.classloader;
// JVM 参数:
//-XX:+TraceClassLoading // 用于追踪类的加载信息并打印出来
//分析项目启动为什么这么慢,快速定位自己的类有没有被加载!
// rt.jar jdk 出厂自带的,最高级别的类加载器要加载的!
public class Demo02 {
public static void main(String[] args) {
System.out.println(MyChild1.str2);
// 运行的结果
/**
* MyParent1 static
* MyChild1 static
* hello,str2
*/
}
}class MyParent1{
public static String str = "hello,world";
static {
System.out.println("MyParent1 static");
}
}class MyChild1 extends MyParent1{
public static String str2 = "hello,str2";
static {
System.out.println("MyChild1 static");
}
}
常量final
package com.coding.classloader;
// 常量
public class Demo03 {
public static void main(String[] args) {
System.out.println(MyParent02.str);
}
}class MyParent02{
public static final String str = "hello world";
static {
System.out.println("MyParent02 static");
// 这句话会输出吗?
}
/**
* final 常量在编译阶段的时候 常量池;
* 这个代码中将常量放到了 Demo03 的常量池中。之后 Demo03与MyParent02 就没有关系了
*/
}
package com.coding.classloader;
import java.util.UUID;
/**
* 当一个常量的值并非编译期间可以确定的,那这个值就不会被方法调用类的常量池中!
* 程序运行期间的时候,回主动使用常用所在的类
*/
public class Demo04 {
public static void main(String[] args) {
System.out.println(MyParent04.str);
}
}class MyParent04{public static final String str = UUID.randomUUID().toString();
static {
System.out.println("MyParent04 static");
// 这句话会输出吗?
}}
ClassLoader分类1、java虚拟机自带的加载器
- BootStrap 根加载器 (加载系统的包,JDK 核心库中的类 rt.jar)
- Ext 扩展类加载器 (加载一些扩展jar包中的类)
- Sys/App 系统(应用类)加载器 (我们自己编写的类)
- ClassLoader,只需要继承这个抽象类即可,自定义自己的类加载器
package com.coding.classloader;
// Demo01
public class Demo01 {public static void main(String[] args) {
Object o = new Object();
// jdk 自带的
Demo01 demo01 = new Demo01();
// 实例化一个自己定义的对象// null 在这里并不代表没有,只是Java触及不到!
System.out.println(o.getClass().getClassLoader());
// null
System.out.println(demo01.getClass().getClassLoader());
// AppClassLoader
System.out.println(demo01.getClass().getClassLoader().getParent());
// ExtClassLoader
System.out.println(demo01.getClass().getClassLoader().getParent().getParent());
// null// 思考:为什么我们刚才自己定义的 java.lang.String 没有生效?// jvm 中有机制可以保护自己的安全;
// 双亲委派机制 : 一层一层的让父类去加载,如果顶层的加载器不能加载,然后再向下类推
// Demo01
// AppClassLoader03
// ExtClassLoader02
// BootStrap (最顶层)01java.lang.Stringrt.jar// 双亲委派机制 可以保护java的核心类不会被自己定义的类所替代
}
}
双亲委派机制【深入理解JVM】双亲委派机制 可以保护java的核心类不会被自己定义的类所替代
一层一层的让父类去加载,如果顶层的加载器不能加载,然后再向下类推
// Demo01
// AppClassLoader03
// ExtClassLoader02
// BootStrap (最顶层)01java.lang.Stringrt.jar