广州企业网站设计公司,常德论坛官网,学校网站建设实训,网站策划和运营1.内存结构概述 类加载子系统负责从文件系统或网络中加载class文件#xff0c;class文件在文件开头有特定的文件标识 ClassLoader只负责class文件的加载#xff0c;至于它是否运行#xff0c;则由Execution Engine决定 加载的类信息存放于一块称为方法区的内存空间#xff…1.内存结构概述 类加载子系统负责从文件系统或网络中加载class文件class文件在文件开头有特定的文件标识 ClassLoader只负责class文件的加载至于它是否运行则由Execution Engine决定 加载的类信息存放于一块称为方法区的内存空间除了类的信息外方法区中还会存放运行时常量池信息可能还包括字符串常量和数字常量 2.类加载器与类的加载过程 加载 1.通过一个类的全限定名获取定义此类的二进制字节流 2.将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构 3.在内存中生成一个代表这个类的java.lang.Class对象作为方法区这个类的各种数据的访问入口 链接:验证、准备、解析 验证 主要包括四种验证文件格式验证,元数据验证,字节码验证,符号引用验证 准备 为类变量分配内存并设置该类变量的默认初始值即零值 这里不包含final修饰的static因为final在编译的时候就会分配了准备阶段会显示初始化 这里不会为实例变量分配初始化类变量会分配在方法区而实例变量是会随着对象一起分配到java堆中 解析 将常量池内的符号引用转换为直接引用的过程 符号引用就是一组符号来描述所引用的目标。 直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄 初始化 初始化阶段就是执行类构造器方法clinit()的过程此方法不需要定义是javac编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来 构造器方法中指令按语句在源文件中出现的顺序执行 cliinit()不同于类的构造器 若该类具有父类jvm会保证子类的cliinit()执行前父类的cliinit()已经执行完毕 虚拟机必须保证一个类的cliinit()方法在多线程下被同步加锁 3.类加载器分类 jvm支持两种类型的类加载器分别为引导类加载器(BootStrap ClassLoader)和自定义类加载器(User-Defined ClassLoader) 从概念上来讲自定义类加载一般指的是程序中由开发人员自定义的一类类加载器但是java虚拟机规范却没有这么定义而是将派生于抽象类ClassLoader的类加载器都划分为自定义类加载器 启动类加载器 这个类加载使用c/c语言实现的嵌套在jvm内部 用来加载java的核心库(JAVA_HOME/jre/lib/rt.jar、resources.jar、sun.boot.class.path路径下的内容)用于提供JVM自身需要的类 并不继承自java.lang.ClassLoader没有父加载器 加载扩展类和应用程序类加载器并指定为他们的父类加载器 出于安全考虑Bootstrap启动类加载器只加载包名为java,javax,sun等开头的类 扩展类加载器 java语言编写由sun.misc.Launcher$ExtClassLoader实现。 派生于ClassLoader类 父类加载器为启动类加载器 从java.ext.dirs系统属性所指定的目录中加载类库或从jdk的安装目录jre/lib/ext子目录(扩展目录)下加载类库。如果用户创建的jar放在此目录下也会自动由扩展类加载器加载 应用程序类加载器 java语言编写由sun.misc.Launcher$AppClassLoader实现 派生于ClassLoader类 父类加载器为扩展类加载器 负责加载环境变量classpath或系统属性java.class.path指定路径下的类库 该类加载器中默认的类加载器一般来说java应用的类都是由它来加载完成 为什么要自定义类加载器 隔离加载类 修改类加载方式 扩展加载源 防止源码泄露 4.ClassLoader的使用说明 5.双亲委派机制 工作原理 1.如果一个类加载器收到了类加载请求它并不会自己先去加载而是把这个请求委托给父类的加载器去执行 2.如果父类加载器还存在其父类加载器则进一步向上委托 3.如果父类加载器可以完成类加载任务就成功返回若父类加载器无法完成加载任务子类加载器尝试自己去加载这就是双亲委派机制 jvm中表示两个class对象是否为同一个类存在两个必要条件 1.类的完整类名必须一致包括包名 2.加载这个类的ClassLoader(指ClassLoader实例对象)必须相同 类加载器的引用 jvm必须知道一个类型是由启动类加载器加载的还是由用户类加载器加载的。如果一个类型是由用户类加载器加载的那jvm会将这个类加载器的一个引用作为类型信息的一部分保存到方法区中当解析一个类型到另一个类型引用的时候jvm要保证这两个类型的类加载器是相同的 类的主动使用和被动使用
类的被动使用不会导致类的初始化