jvm加载器
加载器的加载器不是父类的关系
双亲委派,又称做项目,流程,先问最近的,有没有做过,往上问,最后项目中没有就自己搞
主要是安全问题,进来个东西,自己干不过,请求上级支援,再请求支援。层层申请。
双亲委派,跟加载缓存的过程很像,先看我这有没有这个东西,有的话,就加载没有的话再说
引用马士兵ppt
/**
* 类加载器4个级别
* BootstrapClassLoader
* ExtClassLoader
* AppClassLoader
* CustomClassLoader客户端自定义
*
* Launcher是classLoader的启动类
*/
public class TestClassLoader {
public static void main(String[] args) throws ClassNotFoundException {
//BootstrapClassLoader
System.out.println(String.class.getClassLoader());
System.out.println(sun.awt.HKSCS.class.getClassLoader());
//Launcher$ExtClassLoader
System.out.println(sun.net.spi.nameservice.dns.DNSNameService.class.getClassLoader());
//Launcher$AppClassLoader,我们写的类都是AppClassLoader加载的
System.out.println(TestClassLoader.class.getClassLoader());
System.out.println("-------");
System.out.println(sun.net.spi.nameservice.dns.DNSNameService.class.getClassLoader());
System.out.println(TestClassLoader.class.getClassLoader().getClass().getClassLoader());
System.out.println("----------");System.out.println("-------");
//查看一个class,通过getParent()方法,他的ClassLoader
System.out.println(TestClassLoader.class.getClassLoader().getParent().getParent());
//ExtClassLoader
System.out.println(TestClassLoader.class.getClassLoader().getParent());
//sun.misc.Launcher$AppClassLoader@18b4aac2
System.out.println(TestClassLoader.class.getClassLoader());
System.out.println("-------");System.out.println("-------");
//看不同ClassLoader加载了哪些jar包
System.out.println("BootstrapClassLoader----");
String bootClassPath = System.getProperty("sun.boot.class.path");
System.out.println(bootClassPath.replaceAll(";",System.lineSeparator()));
System.out.println("ExtClassLoader----");
String var0 = System.getProperty("java.ext.dirs");
System.out.println(var0.replaceAll(";",System.lineSeparator()));
System.out.println("AppClassLoader----");
String var1 = System.getProperty("java.class.path");
System.out.println(var1.replaceAll(";",System.lineSeparator()));
System.out.println("-------");System.out.println("-------");
//自定义ClassCloader,通过LoadClass 热部署
Class clazz = TestClassLoader.class.getClassLoader().loadClass("com.example.demo.jvm.TestClassLoader");
System.out.println(clazz.getName());
}
public void hello(){
System.out.println("hello world ali");
}
}
以下是自极客时间的摘抄和总结
虚拟机的好处
-
jvm虚拟机可以由软硬件实现。一次编写,到处运行
-
托管环境。处理代码终得错误。能够处理自动内存管理,垃圾回收。
虚拟机具体是怎样运行 Java 字节码的?
-
从虚拟机视角来看,执行 Java 代码首先需要将它编译而成的 class 文件加载到 Java 虚拟 机中。加载后的 Java 类会被存放于方法区(Method Area)中。实际运行时,虚拟机会执 行方法区内的代码。
Java 虚拟机会将栈细分为面向 Java 方法的 Java 方法栈,面向本地方法(用 C++ 写的 native 方法)的本地方法栈,以及存放各个线程执行位置的 PC 寄存器
![](https://img-blog.csdnimg.cn/20201130233010335.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzcyMTM0Nw==,size_16,color_FFFFFF,t_70)
进入方法 ->java方法栈 -> 栈帧 ->存放局部变量,字节码的操作数
从硬件视角来看,Java 字节码无法直接执行。因此,Java 虚拟机需要将字节码翻译成机器码。
翻译过程2种
-
解释执行: 逐条将字节码翻译成 机器码并执行.好处,无需等待编译(自行车,生物动力)
-
即时编译( Just-In-Time compilation,JIT ): 将一个方法中 包含的所有字节码编译成机器码后再执行。(汽车,物理动力)
不同在于编译的范围
![](https://img-blog.csdnimg.cn/20201130233010334.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzcyMTM0Nw==,size_16,color_FFFFFF,t_70)
Java 虚拟机的运行效率究竟是怎么样的?
不常用的用解释器,小部分热点代码,用jit。
多个jit。 HotSpot 内置了多个即时编译器:C1、C2 和 Graal。 Graal 是 Java 10 正式引入的实验性即时编译器。
C1 又叫做 Client 编译器,面向的是对启动性能有要求的客户端 GUI 程序,采用的优化手段相 对简单,因此编译时间较短
C2 又叫做 Server 编译器,面向的是对峰值性能有要求的服务器端程序,采用的优化手段 相对复杂,因此编译时间较长,但同时生成代码的执行效率较高
Java 虚拟机将
运行时内存区域划分为五个部分,分别为方法区、堆、PC 寄存器、Java 方法栈和本地方法栈。
在run中编辑
-Xmixed混合模式(默认是这个)
-Xint解释模式,启动很快,执行很慢
-Xcomp纯编译模式,执行很快,启动慢
可以测试下,体验下各种模式
public class TestwaytoRun {
public static void main(String[] args) {
for (int i = 0; i < 100000L; i++) {
m();
}
long start = System.currentTimeMillis();
for (int j = 0; j < 100000L; j++) {
m();
}
long end = System.currentTimeMillis();
System.out.println(end -start);
}
//耗费时间
public static void m(){
for (int i = 0; i < 100000L; i++) {
long j = i%3;
}
}
}