这里写目录标题
一 JVM介绍
灰色: 代表线程私有 内存占用较少
橙色: 线程共享 存在垃圾回收
二 类加载器
回忆一下多线程8锁
静态同步方法锁的是上图的Car Class(模板)
非静态同步方法锁的是当前实例对象car1…
1 什么是类加载器
负责加载class文件,class文件在文件开头有特定的文件标示,将class文件字节码内容加载到内存中,并将这些内容转换成方法区中的运行时数据结构并且ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine决定
在文件开头有特定的文件标示
2 类加载器的种类
虚拟机自带的加载器
启动类加载器(Bootstrap)C++
扩展类加载器(Extension)Java
应用程序类加载器(AppClassLoader)Java也叫系统类(SystemClassLoader)加载器,加载当前应用的classpath的所有类
用户自定义加载器
Java.lang.ClassLoader的子类,用户可以定制类的加载方式
例子
package com.luyi.demo;
/**
* @author 卢意
* @create 2021-01-12 16:41
*/
public class ClassLoadDemo {
public static void main(String[] args) {
Object object = new Object();
System.out.println(object.getClass().getClassLoader());
ClassLoadDemo classLoadDemo = new ClassLoadDemo();
System.out.println(classLoadDemo.getClass().getClassLoader().getParent().getParent());// null 不让挖祖坟 哈哈哈
System.out.println(classLoadDemo.getClass().getClassLoader().getParent());// sun.misc.Launcher$ExtClassLoader@78308db1
System.out.println(classLoadDemo.getClass().getClassLoader());// sun.misc.Launcher$AppClassLoader@18b4aac2
}
}
可以这么说 sun.misc.Launcher是Java虚拟机的入口
3 双亲委派机制
- 当一个类收到了类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一个层次类加载器都是如此,因此所有的加载请求都应该传送到启动类加载其中,只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的Class),子类加载器才会尝试自己去加载。
- 采用双亲委派的一个好处是比如加载位于 rt.jar 包中的类 java.lang.Object,不管是哪个加载器加载这个类,最终都是委托给顶层的启动类加载器进行加载,这样就保证了使用不同的类加载器最终得到的都是同样一个 Object对象。
概括一下就是 再加载类的时候先去用BootStrapClassLoad加载,如果找不到该类再用ExtClassLoader加载,如果再找不到就去用AppClassLoader加载
4 沙箱安全机制
上面的双亲加载机制保证了Java原代码不受污染保证程序的安全
三 执行引擎
Execution Engine执行引擎负责解释命令,提交操作系统执行。
四 Native Interface 本地方法接口
native 代表调用的是C语言函数库和操作系统函数库
本地接口的作用是融合不同的编程语言为 Java 所用,它的初衷是融合 C/C++程序,Java 诞生的时候是 C/C++横行的时候,要想立足,必须有调用 C/C++程序,于是就在内存中专门开辟了一块区域处理标记为native的代码,它的具体做法是 Native Method Stack中登记 native方法,在Execution Engine 执行时加载native libraies。
目前该方法使用的越来越少了,除非是与硬件有关的应用,比如通过Java程序驱动打印机或者Java系统管理生产设备,在企业级应用中已经比较少见。因为现在的异构领域间的通信很发达,比如可以使用 Socket通信,也可以使用Web Service等等,不多做介绍。
native方法只有声明 没有实现
Native Method Stack
它的具体做法是Native Method Stack中登记native方法,在Execution Engine 执行时加载本地方法库
五 PC寄存器(程序计数器) Program Countter Register
简单一句话 当前程序结束了 PC寄存器指向下一个程序
- 每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码(用来存储指向下一条指令的地址,也即将要执行的指令代码),由执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不记。
- 这块内存区域很小,它是当前线程所执行的字节码的行号指示器,字节码解释器通过改变这个计数器的值来选取下一条需要执行的字节码指令。
- 如果执行的是一个Native方法,那这个计数器是空的。
- 用以完成分支、循环、跳转、异常处理、线程恢复等基础功能。不会发生内存溢出(OutOfMemory=OOM)错误