📅  最后修改于: 2020-02-10 15:07:58             🧑  作者: Mango
JVM(Java虚拟机)充当运行Java应用程序的运行时引擎。JVM是实际上调用Java代码中存在的main方法的一种。JVM是JRE(Java运行时环境)的一部分。
Java应用程序称为WORA(可在任何地方写入一次)。这意味着程序员可以在一个系统上开发Java代码,并且可以期望它在任何其他启用Java的系统上运行,而无需进行任何调整。由于JVM,所有这些都是可能的。
当我们编译.java文件时,Java编译器会生成具有与.java文件中相同的类名的.class文件(包含字节码)。当我们运行它时,此.class文件进入各个步骤。这些步骤共同描述了整个JVM:
类加载器子系统
它主要负责三个活动。
加载:类加载器读取.class文件,生成相应的二进制数据并将其保存在方法区域中。对于每个.class文件,JVM将以下信息存储在方法区域中。
加载.class文件后,JVM创建类型为Class的对象来表示该文件在堆内存中。请注意,该对象的类型为java.lang包中预定义的Class 。程序员可以使用此Class对象来获取类级别的信息,例如类名称,父名称,方法和变量信息等。要获取此对象引用,我们可以使用Object类的getClass()方法。
// A Jav代码,展示被JVM创建的类实例中,代表.class且被储蓄在内存中的信息
import java.lang.reflect.Field;
import java.lang.reflect.Method;
// 创建测试类
public class Test
{
public static void main(String[] args)
{
Student s1 = new Student();
// 得到claas信息
Class c1 = s1.getClass();
// 打印c1类型
System.out.println(c1.getName());
// 在一个array中得到所有防范
Method m[] = c1.getDeclaredMethods();
for (Method method : m)
System.out.println(method.getName());
// 在一个array中,得到所有fields
Field f[] = c1.getDeclaredFields();
for (Field field : f)
System.out.println(field.getName());
}
}
// 测试代码
class Student
{
private String name;
private int roll_No;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getRoll_no() { return roll_No; }
public void setRoll_no(int roll_no) {
this.roll_No = roll_no;
}
}
输出:
Student
getName
setName
getRoll_no
setRoll_no
name
roll_No
注意:对于每个加载的.class文件,仅创建一个 Class对象。
Student s2 = new Student();
// c2和c1指向同一个实例对象
Class c2 = s2.getClass();
System.out.println(c1==c2); // true
链接:执行验证,准备和(可选)解决方案。
初始化:在此阶段,所有静态变量都分配有在代码和静态块(如果有)中定义的值。在类中从上到下执行,在类层次结构中从上到下执行。
通常,有三种装载机:
// Java代码,展示类载入的子系统
public class Test
{
public static void main(String[] args)
{
// string类被bootstrap载入器载入,bootstrap loader不是java的一个对象,所有是null
System.out.println(String.class.getClassLoader());
// 测试类,被Application载入器载入
System.out.println(Test.class.getClassLoader());
}
}
输出:
null
sun.misc.Launcher$AppClassLoader@73d16e93