JVM类加载器

类的加载指的是将类的.class文件中的二进制数据读取到内存中,将其放在运行时数据的方法区内,然后在内存中创建一个java.lang.Class对象(规范并说明Class对象位于在哪里,HotSpot虚拟机将其放在了方法去中)用来封装类在方法去内的数据结构。

  1. 在java代码中,类型的加载、连接与初始化的过程都是在程序运行期间完成的
  2. 提供了更大的灵活性,增加了更多的可能性

一.类的五个阶段

  1. 加载:查找并加载类的二进制数据
  2. 连接:
    • 验证:确保被加载类的正确性
    • 准备:为类的静态变量分配内存,并将其初始化为默认值
    • 解析:把类中的符号引用转换为直接引用
  3. 初始化:为类的静态变量赋予正确的初始值
  4. 使用
  5. 卸载
//假设
class Test {

    public static int a = 1;

}

//在连接的准备阶段虚拟机会把a赋予默认值0分配空间,而在初始化阶段才会赋予正确的值

二、在如下情况下java虚拟机会结束生命进程

  1. 执行System.exit()
  2. 程序正常执行结束
  3. 程序在执行中遇到错误异常终止
  4. 由于操作系统错误导致的java虚拟性进程终止

三、Java类的使用

  1. Java程序对类的使用方式可以分为两种
    1. 主动使用
    2. 被动使用
  2. 所有的java虚拟机实现必须在每个类的接口被java程序“首次主动使用”时才初始化他们

  1. 主动使用(七种) 本质根据虚拟机的助记符的使用
    1. 创建类的实例             getstatic
    2. 访问某个类或者接口的静态变量,或者对该静态变量赋值     putstatic
    3. 调用类的静态方法        invokestatic
    4. 反射(如Class.forName(“com.test.Test”))
    5. 初始化一个类的子类
    6. Java虚拟机启动时被标明为启动类
    7. Jdk1.7开始提供的动态语言支持:java.lang.invoke.MethodHandler实例的解析结果REF_getStatic,REF_putStatic,REF_invokeStatic句柄的类没有初始化,则进行初始化
  1. 被动使用
    1. 其他使用方式不会导致类的初始化产生,但有可能加载和连接
public class TestClassLoader {

	public static void main(String[] args) {
		System.out.println(Children.value);
		//打印结果为init parent 和 parent
		//Children类并没有被初始化,原因是该类并没有被主动使用
	}
}

class Parent {
	
	public static String value = "parent";
	
	static {
		System.out.println("init parent");
	}
}

class Children extends Parent {
	
	public static String value2 = "child";
	
	static {
		System.out.println("init children");
	}
}

关于类加载与常量池的实例

/**
 * 类加载与常量池
 * @author Administrator
 *
 */

public class TestClassLoader2 {

	public static void main(String[] args) {
		System.out.println(Parent2.value);
		//打印结果为parent
		
		//当使用final关键字后在编译阶段,常量被存入到调用这个方法所在类的常量池中
		//就是说在TestClassLoader2的常量池中,之后TestClassLoader2和Parent2就没有任何关系了
		//甚至,我们可以将Parent2的class删除
		//本质上调用类并不会直接引用到定义常量的类
		//因此并不会触发定义常量的类的初始化
		
	}
}

class Parent2 {
	
	public static final String value = "parent";
	
	static {
		System.out.println("init parent");
	}
}

示例2:

public class TestClassLoader3 {

	public static void main(String[] args) {
		System.out.println(Parent3.value);
		//打印结果为
		//init parent
		//016391ec-6e45-4ffd-a3ed-a3391f633d09
		//当value = UUID.randomUUID().toString()时编译阶段无法获取value的值
		//必须要对类进行初始化后才能得到
		//当一个常量在编译期间无法确定,就不会放到调用类的常量池中
	}
}

class Parent3 {
	
	public static final String value = UUID.randomUUID().toString();
	
	static {
		System.out.println("init parent");
	}
}

四、JVM参数的使用

-XX:+<option>, 表示要开启option选项

-XX:-<option>, 表示要关闭option选项

JVM提供大量参数有些参数默认开启有些默认关闭,”+”,”-”为参数开关

-XX:<option>=<value>

表示将option的值设置为value

五、简单的助记符:

Idc表示将int,float,String类型的常量值从常量池推送至栈顶

bipush表示将单字节(-128,127)的常量值推送至栈顶

sipush表示将一个短整型常量值(-32768,32767)的常量值推送至栈顶

iconst_1表示将int类型1推送至栈顶(-1,0,1,2,3,4,5)特殊

Iconst_m1 表示将int类型-1推送至栈顶

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值