jvm加载类的过程

Java代码从编写到运行的全过程
编写完之后 javac开始将程序编译为.class文件
编译 javac 类名.java java编译一个类时 如果这个类 所依靠的类还没有被编译,则会先编译被依靠的类 然后引用,如果 被编译了 则直接引用, 如果找不到该类所依赖的类的.class或.Java文件 编译器将报“can't find symbol”的错误
编译后的字节码文件格式包括: 常量池和方法字节码。常量池记录了代码所出现的所有的token( 类名,成员变量名等)和符号引用(方法引用,成员变量引用);方法字节码 放的是类中的各个方法的字节码
运行 ①类的加载 在dos窗口运行 java 类名

JVM在程序第一次使用类的时候才会加载类 也就是说并不是一开始把所有的类全都加载到内存中去 一旦程序加载类之后就不再加载了
一个类出现此五种情况会被加载 运行此类main方法 调用此类中的静态成员或方法 反射通过加载class a 创建此类对象 使用此类的子类(情况特殊 当jvm发现某各个有父类 则先将父类加载 连接 初始化 )
①加载(类加载器干的活)
启动类的加载器去加载类 ③最后系统类加载器将自己写的类的class文件的代码放在 内存的方法区/共享区中 在堆中创建一个编译后生成的class文件的对象(字节码对象) class的对象 加载器三种 ①根加载器 将核心类库加载到内存中去 例如:System string object ②扩展加载器 在jre目录下很多class文件 都是扩展的类库 全都由此加载器加载到里面

按照其加载顺序 来加载 归谁管谁加载
②连接并分配内存空间
检查放在方法区中的代码有什么
为其中的静态成员在方法区中再单独分配一块空间(数据共享区) 加载即
解析 将类的二进制数据替换为直接引用 符号等
某类new对象时进入对象堆内存,其类的全局变量一并进堆并赋予其 默认值 然后此对象再和此对象的引用变量创建关系
③初始化
new的东西
若执行代码 某对象的方法
二 类的执行
当运行到类名.方法时 方法就会压栈从方法区进入到栈区 然后执行完之后就出栈死亡结束
JVM JRE jdk 三者
JVM (java虚拟机) 他是虚构出来的计算机,是通过模拟实际的计算机上的功能来实现的
其包括: 栈 , 垃圾回收堆, 一组寄存器,一套字节码指令集,方法域 JVM屏蔽了与具体操作系统有关的信息,使的Java程序只需要面对Java虚拟机即可 其余事由Java虚拟机来做 JVM执行字节码时会 解释成具体平台的 机器指令执行
JRE(Java运行时环境) Java平台 包含Java运行时核心类库。所有的Java程序都要在JRE下运行 他同时也是操作系统下的一个程序的一个进程 拥有其生存周期 包含jvm
jdk 程序开发者用来编译、调试Java程序的开发工具包。
JVM原理
JVM是Java编译器和os平台的虚拟处理器(暂时理解为JVM进行处理使.class变成能被相应的操作系统执行的机器码) 负责与操作系统的交互,操作系统分给jvm内存 jvm屏蔽掉得到的内存的操作系统环境
JVM执行程序的过程 加载.class文件 管理并分配内存 执行垃圾收集
启动
运行 主函数作为该程序初始线程的起点 两种线程 守护线程和非守护线程
消亡 所有的非守护线程终止时,JVM才退出
运行时开辟一块运行时数据区

运行时数据区包括:虚拟机栈区,堆区,方法区,本地方法栈,程序计数器
虚拟机方法栈区: 也就是栈区, 线程私有,存放 局部基本数据类型 方法 非基本数据类型对象的引用 部分的返回结果, 在编译期间完成分配 调用方法时方法进栈
堆区:gc堆,所有的 线程共享,存放对象的实例和数组,Java堆是垃圾回收的主要区域 全局变量
方法区: 线程共享,存储被虚拟机加载的类信息(名称 修饰符),final类型的常量,静态变量,即时编译器编译后的代码等数据。这个区域的内存回收主要针对常量池的对象的回收和对类型的卸载
程序计数器: 线程私有,每个线程都有自己独立的程序计数器,用来指示下一条指令的地址表示当前线程执行的字节码执行到第几行了
本地方法栈 支持native方法的执行 用于存储每个native方法调用的状态
方法 对象 对象的引用 全局变量 局部变量 静态方法 静态变量 final修饰的变量 方法 静态代码块 线程

猜你喜欢

转载自blog.csdn.net/qq_38427463/article/details/79858932