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学习笔记类的加载过程的主要内容,如果未能解决你的问题,请参考以下文章

[jvm学习笔记]-类加载过程

JVM学习笔记3:内存溢出的十个场景

JVM类加载原理学习笔记

Java学习笔记—JVM的类加载机制

深入理解JVM学习笔记——-7虚拟机类加载机制★

深入理解JVM学习笔记——-7虚拟机类加载机制★