前言:

本文内容:JVM学习方式、JVM体系结构、类加载器及双亲委派机制

推荐免费JVM快速入门视频:【狂神说Java】JVM快速入门篇_哔哩哔哩_bilibili

JVM学习方式

面试提问

  • 请你谈谈你对JVM的理解?Java8虚拟机和之前的变化更新?
  • 什么是OOM,什么是栈溢出StackOverFlowError?怎么分析?
  • JVM的常用调优参数有哪些?
  • 内存快照如何抓取,怎么分析Dump文件?
  • 谈谈JVM中,类加载器你的认识?

学习内容预览

  1. JVM的位置
  2. JVM的体系结构
  3. 类加载器
  4. 双亲委派机制
  5. 沙箱安全机制
  6. Native
  7. PC寄存器
  8. 方法区
  9. 三种JVM
  10. 新生区、老年区
  11. 永久区
  12. 堆内存调优
  13. GC–常用算法
  14. JMM
  15. 总结

JVM体系结构

JVM的位置

38

JVM的体系结构

37

类加载器及双亲委派机制

类加载器

作用:加载Class文件

36

User.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package demo01;

/**
* @author Joker大雄
* @data 2022/8/11 - 10:59
**/
public class User {

public static void main(String[] args) {
// 类是模板,对象是具体的
User user1 = new User();
User user2 = new User();
User user3 = new User();
// new 对象的hashCode
System.out.println(user1.hashCode());
System.out.println(user2.hashCode());
System.out.println(user3.hashCode());

Class<? extends User> aClass1 = user1.getClass();
Class<? extends User> aClass2 = user2.getClass();
Class<? extends User> aClass3 = user3.getClass();

// 模板的hashCode
System.out.println(aClass1.hashCode());
System.out.println(aClass2.hashCode());
System.out.println(aClass3.hashCode());
}
}

运行结果

1
2
3
4
5
6
7
8
460141958
1163157884
1956725890
685325104
685325104
685325104

Process finished with exit code 0

四种加载器

  1. 虚拟机自带的加载器
  2. 启动类(根)加载器
  3. 扩展加载器
  4. 应用程序(系统类)加载器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package demo01;

/**
* @author Joker大雄
* @data 2022/8/11 - 10:59
**/
public class User {

public static void main(String[] args) {
// 类是模板,对象是具体的
User user1 = new User();
Class<? extends User> aClass1 = user1.getClass();
// AppClassLoader
ClassLoader classLoader = aClass1.getClassLoader();
// AppClassLoader
System.out.println(classLoader);
// ExtClassLoader 位置:\jre\lib\ext
System.out.println(classLoader.getParent());
// null 不存在或者调用不到 位置:rt.jar
System.out.println(classLoader.getParent().getParent());
}
}

运行结果

1
2
3
4
5
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@1540e19d
null

Process finished with exit code 0

双亲委派机制

执行步骤

  1. 类加载器收到请求
  2. 将这个请求向上委托给父类加载器完成,一直向上委托,直到启动类加载器
  3. 启动类加载器检查是否能够加载当前这个类,能加在就结束,使用当前加载器,否则抛出异常,通知子加载进行加载
  4. 重复步骤3

简单测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package java.lang;

/**
* @author Joker大雄
* @data 2022/8/11 - 11:15
**/
public class String {
/* 双亲委派机制:安全
App-->EXC-->BOOT(最终执行跟加载器里的)
如果BOOT没有,就在EXC中找
如果EXC没有,就在App中找
*/

public String toString(){
return "Jokerdig";
}

public static void main(String[] args) {
String str = new String();
//会报错 因为它最终执行的是BOOT里的,并非我们上方定义的
str.toString();
}
}

运行结果

1
2
3
4
5
错误: 在类 java.lang.String 中找不到 main 方法, 请将 main 方法定义为:
public static void main(String[] args)
否则 JavaFX 应用程序类必须扩展javafx.application.Application

Process finished with exit code 1