JVM学习笔记类的加载过程
Posted 九死九歌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM学习笔记类的加载过程相关的知识,希望对你有一定的参考价值。
一、类的生命周期概述
二、类的加载阶段 Loading
1 加载完成的操作
2 二进制流的获取
3 类模型与class实例的位置
反射的使用:
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Test
public static void main(String[] args)
try
Class<?> cls = Class.forName("java.lang.String");
Method[] ms = cls.getDeclaredMethods();
for(Method m : ms)
String mod = Modifier.toString(m.getModifiers());
System.out.print(mod + " ");
String returnType = m.getReturnType().getSimpleName();
System.out.print(returnType + " ");
System.out.print(m.getName() + "(");
Class<?>[] pt = m.getParameterTypes();
if (pt.length == 0) System.out.print(')');
for (int i = 0; i < pt.length; i++)
char end = (i == pt.length - 1) ? ')' : ',';
System.out.print(pt[i].getSimpleName() + end);
System.out.println();
catch (ClassNotFoundException e)
e.printStackTrace();
3 数组类的加载
三、类的链接阶段 Linking
1 链接阶段的验证环节 Verification
2 链接阶段的准备环节 Prepare
3 链接阶段的解析环节 Resolution
四、类的初始化阶段 Initialization
1 类的初始化过程
被static final修饰的引用变量是在初始化阶段进行赋值。但也有特例,例如static final修饰的String类型,如果是字面量方式进行赋值,那也是连接环节的准备阶段就进行赋值。或者像这样int a = new Random().nextInt();也是在初始化阶段赋值。
2 <clinit>()的线程安全性
如下是通过<clinit>()实现的死锁:
package com.spd.jvm;
class A
static
try
Thread.sleep(1000);
Class.forName("com.spd.jvm.B");
catch (InterruptedException | ClassNotFoundException e)
e.printStackTrace();
System.out.println("A finish init.");
class B
static
try
Thread.sleep(1000);
Class.forName("com.spd.jvm.A");
catch (InterruptedException | ClassNotFoundException e)
e.printStackTrace();
System.out.println("B finish init.");
class DeadLockThread extends Thread
private final char flag;
public DeadLockThread(char flag)
this.flag = flag;
this.setName("Thread" + flag);
public void run()
try
Class.forName("com.spd.jvm." + flag);
catch(ClassNotFoundException e)
e.printStackTrace();
public class Test
public static void main(String[] args)
DeadLockThread a = new DeadLockThread('A');
DeadLockThread b = new DeadLockThread('B');
a.start();
b.start();
3 类的主动使用和被动使用
主动使用中第八点和被动使用第四点了解一下就行,目前无需掌握。
五、类的卸载 Unloading
六、类加载器的概述
1 概述
2 类加载器的分类
package com.spd.jvm;
class User
public class Test
public static void main(String[] args)
User user = new User(); // 隐式加载
try
Class cls = Class.forName("com.spd.jvm.User"); // 显式加载
ClassLoader.getSystemClassLoader().loadClass("com.spd.jvm.User"); // 显式加载
catch (ClassNotFoundException e)
e.printStackTrace();
3 类加载器的必要性
七、类加载器的命名空间与类加载器的分类
1 类加载器的命名空间
同一个字节码文件被两个不同的类加载器加载,那就是两个类。
2 类加载器的分类
上面这个图中,除了Bootstrap是用c/c++实现,其余都是用java实现的。
(这个描述咋听起来像装饰模式)
八、关于不同类加载器的一些说明
1 启动类加载器
加入+TraceClassLoading这个参数,就能输出上面这种信息。
2 扩展类加载器
3 系统类加载器
4 用户自定义类加载器
数组对象的类加载器获取后打印出来是null,因为他不需要类加载器,自然也就没有。
以上是关于JVM学习笔记类的加载过程的主要内容,如果未能解决你的问题,请参考以下文章