java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > JVM运行与类加载全过程

JVM核心教程之JVM运行与类加载全过程详解

作者:AskHarries

我们都知道一个java程序运行要经过编译和执行,但是这太概括了,中间还有很多步骤,下面这篇文章主要给大家介绍了关于JVM核心教程之JVM运行与类加载全过程的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。

为什么要使用类加载器?

Java语言里,类加载都是在程序运行期间完成的,这种策略虽然会令类加载时稍微增加一些性能开销,但是会给java应用程序提供高度的灵活性。例如:

1.编写一个面向接口的应用程序,可能等到运行时再指定其实现的子类;

2.用户可以自定义一个类加载器,让程序在运行时从网络或其他地方加载一个二进制流作为程序代码的一部分;(这个是Android插件化,动态安装更新apk的基础)

为什么研究类加载全过程?

类加载机制

JVM把class文件加载到内存,并对数据进行校验、解析和初始化,最终形成JVM可以直接使用的java类型的全过程。

加载

将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区中的运行时数据结构,在堆中生成一个代表这个类的java.lang.Class对象,作为方法区类数据的访问入口,这个过程需要类加载器参与。

链接

将java类的二进制代码合并到JVM的运行状态之中的过程

初始化

例1:

public class Demo01 {
 public static void main(String[] args) {
  A a = new A();
  System.out.println(a.width);
 }
}

class A{
 public static int width=100; //静态变量,静态域 field
 static{
  System.out.println("静态初始化类A");
  width = 300 ;
 }
 public A() {
  System.out.println("创建A类的对象");
 }
}

分析:


说明:

内存中存在栈、堆(放创建好的对象)、方法区(实际也是一种特殊堆)

1、JVM加载Demo01时候,首先在方法区中形成Demo01类对应静态数据(类变量、类方法、代码…),同时在堆里面也会形成java.lang.Class对象(反射对象),代表Demo01类,通过对象可以访问到类二进制结构。然后加载变量A类信息,同时也会在堆里面形成a对象,代表A类。

2、main方法执行时会在栈里面形成main方法栈帧,一个方法对应一个栈帧。如果main方法调用了别的方法,会在栈里面挨个往里压,main方法里面有个局部变量A类型的a,一开始a值为null,通过new调用类A的构造器,栈里面生成A()方法同时堆里面生成A对象,然后把A对象地址付给栈中的a,此时a拥有A对象地址。

3、当调用A.width时,调用方法区数据。

当类被引用的加载,类只会加载一次

类的主动引用(一定会发生类的初始化)

类的被动引用(不会发生类的初始化)

例2:

public class Demo01 {
 static{
  System.out.println("静态初始化Demo01");
 }
 
 
 public static void main(String[] args) throws Exception {
  System.out.println("Demo01的main方法!");
  System.out.println(System.getProperty("java.class.path"));
  
  //主动引用
//  new A();
//  System.out.println(A.width);
//  Class.forName("com.sinosoft.test.A");
  
  
  //被动引用
//  System.out.println(A.MAX);
//  A[] as = new A[10];
  System.out.println(B.width);//B类不会被加载
  
 }
}

class B extends A {
 static {
  System.out.println("静态初始化B");
 }
}

class A extends A_Father {
 public static int width=100; //静态变量,静态域 field
 public static final int MAX=100; 
 
 static {
  System.out.println("静态初始化类A");
  width=300;
 }
 public A(){
  System.out.println("创建A类的对象");
 }
}

class A_Father extends Object {
 static {
  System.out.println("静态初始化A_Father");
 }
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

您可能感兴趣的文章:
阅读全文