JVM: java虚拟机
jvm运行我们编写的.java文件转换后的.class文件
问题一 :Class在本地磁盘上 如何记载到jvm中
问题二:jvm又是如何加载java程序所使用的系统类(系统jar 第三方jar)?
解决方案 :使用java中的类加载器 类加载器是jvm的一部分
类加载器不是一个 当jvm运行
类加载器
运行
-
当jvm运行 先运行应用程序类加载器 判断是否有父加载器 有则启动父加载器
-
启动扩展类加载器 启动后检测是否有 父加载器
-
启动 启动类加载器(最上层的 父加载器)
加载
-
启动类加载器先加载 加载jre/lib的jar
-
然后加载扩展类加载器 加载jre/lib/ext下的jar
-
应用程序类加载器进行加载 加载classpath(自己编写的类) 自己编写的类的编译的的class文件
【说明】
当一个类被父加载器加载了 子加载器就不会加载
面试题:自己编写和系统类完全一样的类 能否被执行?
java.lang 类:String
答案:不能被执行 因为被系统的父类加载器加载了 自己的不会被加载到
双亲委派机制的作用 :确保java的安全,不让自己写的类替换掉Java中的类 自己的不会被加载到。
类文件的加载过程
类加载器加载一个.class文件分五步
- 加载
- 验证
- 准备
- 解析
- 初始化
加载loading
反射的过程(读的过程)把class文件读取到jvm中
验证Cerification
验证,class文件的格式(语法),访问修饰符,方法的参数,局部变量是否赋值,类型是否匹配
保证文件是java虚拟机是认识的
准备Preparation
检查有没有静态变量 有就给静态变量直接分配内存 并设置初始值 正式值还没赋呢
解析
给final成员赋值
String str=“abc”;String str2=“abc”;地址也一样
初始化Resolution
给静态变量的值赋实际值
JVM的内存模型
jvm:是一个程序 成为java虚拟机 运行java程序的 jdk包含jre jre包含jvm
jvm的组成:
- 类加载器
- 执行引擎
- 运行时数据区
jvm内存模型主要值运行时数据区是如何划分的
运行时数据区分五个部分:
-
方法区:
- 存放类加载器加载的类对象
- static成员
- final常量池
-
虚拟机栈:存放方法中声明的局部变量
先进后出的栈结构
-
程序计数器:因为java是多线程 每个线程都有一个程序记录器 记录到执行到第几行 轮转回来接着执行
-
本地方法栈:存放第三方的内容
-
堆:存放new出来的对象 垃圾回收只回收堆里面的
线程共享:方法区 堆 里面的内容
线程私有,线程隔离:程序计数器 虚拟机栈 本地方法栈