• 实战JAVA虚拟机 JVM故障诊断与性能优化(九)---Class装载系统


    Class文件的装载流程

      只有被Java虚拟机装载的Class类型才能在程序中使用。

      Class文件装载过程:

        

      类装载的条件

        Class只有在必须使用的时候才会被装载,Java虚拟机不会无条件地装载Class类型。Java虚拟机规定,一个类或接口在初次使用前,必须要进行初始化。“使用”指主动使用。

      加载类

        在加载类时,Java虚拟机完成:

        1、通过类的全名,获取类的二进制数据流。

        2、解析类的二进制数据流为方法区内的数据结构

        3、创建java.lang.Class类的实例,表示该类型

      虚拟机可以通过文件系统读入一个Class后缀文件,或者jar,zip等归档数据包。在获取到类的二进制信息后,java虚拟机就会处理这些数据,并最终转为一个java.lang.Class的实例,

      java.lang.Class实例是访问类型元数据的接口,也是实现反射的关键数据,通过Class类提高的接口,可以访问一个类型的方法、字段和信息。

      验证类

        当类加载到系统后,

          

      准备

        java虚拟机为各类型变量默认的初始值。

        

        注:java并不支持boolean型,内部实现为int,由于int默认是0,故boolean默认就是false

      解析类

        解析阶段的工作,将类、接口、字段和方法的符号引用转为直接引用。  

        以字节码调用了System.out.println()为例:

        

      初始化

        如果前面都没有问题,类开始执行Java字节码。初始化阶段的重要工作是执行类的初始化方法<clinit>。方法<clinit>是由编译器自动生成的,它是由类静态成员的赋值语句以及static语句块合并产生的。

        如果一个类没有赋值语句,也没有static语句块,那么生成的<clinit>函数就应该是空,因此,编译器就不会为该类插入<clinit>函数。

        对于<clinit>函数的调用,也就是类的初始化,虚拟机会在内部确保其多线程环境的安全性,也就是说,当多个线程试图初始化同一个类时,只有一个线程可以进入<clinit>函数,而其他线程必须等待,

        如果之前线程已经初始化好了,直接返回给它已经准备好的信息。

        正因为函数<clinit>是线程安全的,因此,在多线程环境下进行类初始化时,可能会引起死锁,并且这种死锁很难发现,因此看起来没有死锁一样。可以通过对堆Dump的分析解决。

     

       

  • 相关阅读:
    mysql中txt的导入及导出
    邮箱手机正则
    用yum安装完mysql后没有mysqld的问题
    利用php在图片上写字(中英文)
    修改MYSQL密码及权限
    mysql 索引!
    MySQL对表的复制,修改及删除
    防止表单重复提交!
    Linux学习篇SVN命令详解
    Linux 安装PHP配置参数
  • 原文地址:https://www.cnblogs.com/kaishi/p/7829307.html
Copyright © 2020-2023  润新知