原文:https://blog.csdn.net/wy11933/article/details/80254223
1、根据JVM内存配置要求,为JVM申请特定大小的内存空间;
JVM启动时按照其配置要求,申请一块内存,并根据JVM规范和实现将内存划分为几个区域。class二进制文件信息被放入“方法区”,对象实例被放入“java堆”等。关于JVM内存模型内容参考 JVM(一)JVM内存模型
2、创建一个引导类加载器实例,初步加载系统类到内存方法区区域中;
JVM申请好内存空间后,JVM会创建一个引导类加载器(Bootstrap Classloader)实例,引导类加载器是使用C++语言实现的,负责加载JVM虚拟机运行时所需的基本系统级别的类,如java.lang.String, java.lang.Object等等。 (这也是为什么我们不能自定义java.lang.String类)
引导类加载器(Bootstrap Classloader)会读取{JRE_HOME}/lib下的jar包和配置,然后将这些系统类加载到方法区内。
引导类加载器将类信息加载到方法区中,以特定方式组织,对于某一个特定的类而言,在方法区中它应该有 运行时常量池、类型信息、字段信息、方法信息、类加载器的引用,对应class实例的引用等信息。
3、创建JVM 启动器实例 Launcher,并取得类加载器 ClassLoader;
此时,JVM虚拟机调用已经加载在方法区的类sun.misc.Launcher 的静态方法 getLauncher(), 获取 sun.misc.Launcher 实例
4、使用上述获取的 ClassLoader 实例加载我们定义的类;
通过 launcher.getClassLoader() 方法返回 AppClassLoader 实例,接着就是 AppClassLoader 加载 我们自定义类.
加载自己写的类之前先要加载我们写的类中用到的其他类。在 org.luanlouis.jvm.load.Main 类被编译成的class文件中有一个叫常量池(Constant Pool)的结构体,通过这个常量池中的 CONSTANT_CLASS_INFO 常量判断该class用到了哪些类,并通过类加载器去加载这些类。
5、加载完成时候JVM会执行Main类的main方法入口,执行Main类的main方法;
6、结束,java程序运行结束,JVM销毁。