【狂神说Java】JVM快速入门篇

双亲委派机制
java是运行在java虚拟机(JVM)中的,在java文件编译成class字节码文件后,由ClassLoader(类加载器)负责讲这些class文件给加载到JVM中去运行
JVM提供了三层的ClassLoader:
- BootStrapClassLoader:主要是负责加载核心的类库(如:java.lang.*等)构造ExtClassLoader和AppClassLoader。(主要是rt.jar,charset.jar等包)
- ExtClassLoader:主要负责加载jre/lib/ext目录下的一些扩展的jar。
- AppClassLoader:主要负责加载应用程序的主函数。
那如果有一个我们写的Hello.java编译成的Hello.class文件,它是如何被加载到JVM中的呢?
java.lang包下的loadClass方法:
public Class<?> loadClass(String name) throws ClassNotFoundException { return loadClass(name, false); } // -----??----- protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { // 首先,检查是否已经被类加载器加载过 Class<?> c = findLoadedClass(name); if (c == null) { try { // 存在父加载器,递归的交由父加载器 if (parent != null) { c = parent.loadClass(name, false); } else { // 直到最上面的Bootstrap类加载器 c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { // If still not found, then invoke findClass in order // to find the class. c = findClass(name); } } return c; }
如果没有加载过,会一直向上提交,直到顶层的BootStrapClassLoader,再向下检查是否能加载该类。如果一直到最底层都没有任何加载器能加载此类,则抛出ClassNotFoundException。
类加载生命周期
- 加载-将.class文件从磁盘读到内存
- 连接
- 2.1 验证-验证字节码的正确性。
- 2.2 准备-给类的静态变量分配内存,并赋予默认值
- 2.3 解析-类装载器装入类所引用的其他所有类。
- 初始化-为类的静态变量赋予正确的初始值,上述的准备阶段为静态变量赋予的是虚拟机默认的初始值,此处赋予的才是程序编写着为变量分配的真正的初始值,执行静态代码块
- 使用
- 卸载