物理机:
jvm:
Java虚拟机与物理机
有哪些版本?
最常用的目前是HotSpot,可以通过java -version命令查看
官网: https://docs.oracle.com/javase/8/docs/index.html
jre 包含了jvm,jdk 包含jdk
https://www.oracle.com/technetwork/tutorials/tutorials-1876574.html
Java源码文件、Kotlin源码文件、Groovy源码文件等都可以编译成class文件执行。
public class User {
private Integer age;
private String name = "Jack";
private Double salary = 100.0;
private static String address;
public void say() {
System.out.println("Jack Say...");
}
public static Integer calc(Integer op1, Integer op2) {
op1 = 3;
Integer result = op1 + op2;
return result;
}
}
javac User.java->User.class
官方文档
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html
class 文件是一个16进制的文件
IDEA插件(BindED)——查看class文件的十六进制
文件的格式
ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
user.class对应的16进制文件
对比类文件的格式,和上面16进制数据进行解析
cafebabe
u4 magic 对应的就是16进制中的 cafebabe ,cafebabe 代表的是一个class类文件的表示,只要是一个class文件就一定是 cafebabe 开头
0000+0034:minor_version+major_version
16进制的34等于10进制的52,表示JDK的版本为8
0043:constant_pool_count
16进制的43等于10进制的67,表示常量池中常量的数量是66
cp_info:constant_pool[constant_pool_count-1]
字面量:文本字符串,final修饰的常量等
符号引用:类和接口的全限定名、字段名称和描述符、方法名称和描述符
The constant pool
官网: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4
常量的基本结构
cp_info {
2u1 tag;
u1 info[];
}
javap ‐v ‐c ‐p User.class > User.txt 进行反编译,查看字节码信息和指令等信息
JVM相对class文件来说可以理解为是操作系统;class文件相对JVM来说可以理解为是汇编语言或者机 器语言。
官网:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html
try {
if (parent != null) {
// 先找父加载器
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
public class Demo {
public static void main(String[] args) {
// App ClassLoader
System.out.println(new Demo().getClass().getClassLoader());
// Ext ClassLoader
System.out.println(new Demo().getClass().getClassLoader().getParent());
// Bootstrap ClassLoader
System.out.println(new Demo().getClass().getClassLoader().getParent().getParent());
}
}
结果
bootstrap classloader 是c语言实现的打印不出来
(2)SPI机制
(3)OSGi
保证被加载类的正确性
为类的静态变量分配内存,并将其初始化为默认值
把类中的符号引用转换为直接引用
对类的静态变量,静态代码块执行初始化操作
官网:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5
JVM运行时数据区是一种规范,真正的实现在JDK 8中就是Metaspace,在JDK6或7中就是Perm Space方法区是各个线程共享的内存区域,在虚拟机启动时创建,虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却又一个别名叫做Non-Heap(非堆),目的是与Java堆区分开来。用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。当方法区无法 满足内存分配需求时,将抛出OutOfMemoryError异常。