zoukankan      html  css  js  c++  java
  • 关于JVM类加载的过程

    因为我的java基础并不是很好,所以可以从源码看起,遇到不懂得即可查资料来补全我的缺陷。因为公司一直做的是java web项目,所以我从tomcat的源码开始看起。
    这里用的是tomcat8.0的源代码,有兴趣可以自己去下载。这里有一点要提的是tomcat7的源码编译需要用ant来编译,环境jdk1.6,1.7是不行的。具体可参考  http://www.cnblogs.com/lanxuezaipiao/p/3640923.html

    我们可以发现tomcat启动类bootstrap中存在很多的类变量,即为类中static类型的变量以及static代码块。
    类在jvm中被加载时要经历三个过程。(引用自http://www.blogjava.net/GavinMiao/archive/2011/09/01/357739.html)
    关于JVM还可以参考 http://blog.hesey.net/2011/04/introduction-to-java-virtual-machine.html 

    1):类加载load:从字节码二进制文件——.class文件将类加载到内存,从而达到类的从硬盘上到内存上的一个迁移,所有的程序必须加载到内存才能工作。将内存中的class放到运行时数据区的方法区内,之后在堆区建立一个java.lang.Class对象,用来封装方法区的数据结构。这个时候就体现出了万事万物皆对象了,干什么事情都得有个对象。就是到了最底层究竟是鸡生蛋,还是蛋生鸡呢?类加载的最终产物就是堆中的一个java.lang.Class对象。

    2):连接:连接又分为以下小步骤

    验证:出于安全性的考虑,验证内存中的字节码是否符合JVM的规范,类的结构规范、语义检查、字节码操作是否合法、这个是为了防止用户自己建立一个非法的XX.class文件就进行工作了,或者是JVM版本冲突的问题,比如在JDK6下面编译通过的class(其中包含注解特性的类),是不能在JDK1.4的JVM下运行的。

    准备:将类的静态变量进行分配内存空间、初始化默认值。(对象还没生成呢,所以这个时候没有实例变量什么事情)

    解析:把类的符号引用转为直接引用(保留)

    3):类的初始化: 将类的静态变量赋予正确的初始值,这个初始值是开发者自己定义时赋予的初始值,而不是默认值。

    2. 类的主动使用与被动使用

    以下是视为主动使用一个类,其他情况均视为被动使用!

    1):初学者最为常用的new一个类的实例对象(声明不叫主动使用)

    2):对类的静态变量进行读取、赋值操作的。

    3):直接调用类的静态方法。

    4):反射调用一个类的方法。

    5):初始化一个类的子类的时候,父类也相当于被程序主动调用了(如果调用子类的静态变量是从父类继承过来并没有复写的,那么也就相当于只用到了父类的东东,和子类无关,所以这个时候子类不需要进行类初始化)。

    6):直接运行一个main函数入口的类。

    所有的JVM实现(不同的厂商有不同的实现,有人就说IBM的实现比Sun的要好……)在首次主动调用类和接口的时候才会初始化他们。

    其中有一个例子,可供参考

    1. package test01;    
    2.     
    3. class Singleton {    
    4.     
    5.     public static Singleton singleton = new Singleton();    
    6.     public static int a;    
    7.     public static int b = 0;    
    8.     
    9.     private Singleton() {    
    10.         super();    
    11.         a++;    
    12.         b++;    
    13.     }    
    14.     
    15.     public static Singleton GetInstence() {    
    16.         return singleton;    
    17.     }    
    18.     
    19. }    
    20.     
    21. public class MyTest {    
    22.     
    23.        
    24.     public static void main(String[] args) {    
    25.         Singleton mysingleton = Singleton.GetInstence();    
    26.         System.out.println(mysingleton.a);    
    27.         System.out.println(mysingleton.b);    
    28.     }    
    29.     
    30. }  

    我们分析下,以上代码static变量,在类加载的连接过程中,已经被赋予默认值

    即 singleton =null;a=0;b=0

    在初始化时,首先调用构造函数 使得singleton实例化,a=1;b=1;

    接着开始有对 b=0 进行赋值


    则最后会打印出 a=1;b=0


  • 相关阅读:
    Java 蓝桥杯 算法训练 貌似化学
    Java 蓝桥杯 算法训练 貌似化学
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    JAVA-蓝桥杯-算法训练-字符串变换
    Ceph:一个开源的 Linux PB 级分布式文件系统
    shell 脚本监控程序是否正在执行, 如果没有执行, 则自动启动该进程
  • 原文地址:https://www.cnblogs.com/vikeria/p/4374955.html
Copyright © 2011-2022 走看看