- 浏览: 197728 次
- 性别:
- 来自: 南京
文章分类
最新评论
-
hahalzb:
请问文件解压缩的密码是什么呀
JMS简介与ActiveMQ实战 -
ershimengx:
JMS&ActiveMQ实战(JMS+ActiveMQ ...
JMS简介与ActiveMQ实战 -
lgh1992314:
zenghuiss 写道我书读的少,你不要蒙我哦。。。over ...
Java method invoke的指令简介 -
P00116:
...
JMS简介与ActiveMQ实战 -
风会停息丶:
你好,下载完成后解压密码是多少,跟网盘下载密码一样吗
JMS简介与ActiveMQ实战
Java类装载器子系统
在Java虚拟机中,负责查找并装载类型的那部分被称为类装载子系统。上图描述了,类装载器在JVM组成中的位置。
Java虚拟机有两种类装载器:启动类装载器和用户自定义类装载器。前者是Java虚拟机实现的一部分,后者则是Java程序的一部分。由不同的类装载器装载的类将被放在虚拟机内部的不同命名空间中。
类装载器子系统涉及Java虚拟机的其他几个组成部分,以及几个来自java.lang库的类。比如,用户自定义的类装载器是普通的Java对象,他的类必须派生自java.lang.ClassLoader类。ClassLoader中定义的方法为程序提供了访问类装载器机制的借口。此外,对于每一个被装载的类型,Java虚拟机都会为它创建一个java.lang.Class类的实例来代表该类型。和其他所有对象一样,用户自定义的类装载器以及Class类的实例都放在内存中的堆区,而装载的类型信息则都位于方法区。
装载、连接以及初始化
类装载器子系统出来要定位和导入二进制class文件外,还必须负责验证被导入类的正确性,为类变量分配并初始化内存,以及帮助解析符号引用。这些动作必须严格按以下顺序进行:1)装载(Load)-------查找并装载类型的二进制数据
2)连接(Link)-------执行验证,准备,以及解析(可选)。
验证(Verify) 确保被导入类型的正确性
准备(Prepare) 为类变量分配内存,并将其初始化为默认值
解析(Resolve) 把类型中的符号引用转换为直接引用
3)初始化(Initialize)------把类变量初始化为正确初始值
启动类装载器
只要符合Java class文件格式的二进制文件,Java虚拟机实现都必须能够从中辨别并装载其中的类和接口。某些 虚拟机实现也可以识别其他的非规范的二进制格式文件,但它必须能够辨别class文件。
每个java虚拟机实现都必须有一个启动类装载器,它知道怎么装载受信任的类,比如java api的class文件。Java虚拟机规范并未规定启动类装载器如何去寻找class文件,这又是一件保留给具体的实现设计者去决定的事情。
只要给定某个类型的全限定名,启动类装载器就必须能够以某种方式得到定义该类型的数据。比如,在Window 98平台上,Sun的JDK 1.1是这样工作的:首先它逐个搜索用户在CLASSPATH环境变量中定义的目录,直到找到一个名为”该类型名+.class“的文件为止。除非该类型属于某个未命名的包,否则启动类装载器会在CLASSPATH包含的目录的子目录中寻找这样一个文件,这些子目录的路径名是根据类型的包名称构建的。比如,如果启动类装载器正在搜索这样一个类:java.lang.Object,那么它将在每一个CLASSPATH包含的目录下,查找java\lang这样的一个字目录,以及其中的Object.class文件。
在Sun的JDK 1.2中,与1.1版本不同,启动类装载器将只在系统类(java api的类文件)的安装路径中查找要装入的类;而搜索CLASSPATH目录的任务,现在交给了系统类装载器-----它是一个自定义的类装载器,当虚拟机启动时就被自动创建。
用户自定义类装载器
尽管”用户自定义类装载器“本身是java程序的一部分,但类ClassLoader中的四个方法时通往Java虚拟机的通道:
protected Class<?> defineClass(String name, byte[] data, int off, int len) ; protected Class<?> defineClass(String name, byte[] data, int off, int len, ProtectionDomain protectionDomain) ; protected Class<?> findSystemClass(String name); protected void resolveClass(Class<?> c) ;
任何Java虚拟机实现都必须把这些方法连到内部的类装载器子系统中。
两个被重载的defineClass()方法都要接受一个名为data的字节数组作为输入参数,并且在data[offset]到data[offset + length]之间的二进制数据必须符合Java class文件格式-------它表示一个新的可用类型。而name参数是个字符串,他指出该类型的全限定名。当使用第一个defineClass()时,该类型将被赋予默认的保护域。使用第二个defineClass()时,改类型的保护域将有他的protectionDomain参数指定。每个Java虚拟机实现都必须保证ClassLoader类的defineClass()方法能够把新类型导入到方法区中。
findSystemClass()方法接受一个字符串作为参数,他指出将被装入类型的全限定名。在版本1.0和版本1.1中,这个方法会通过启动类装载器来装载指定类型。如果启动类装载器装载完成,他会返回对Class对象(改对象描述了该类型)的引用。如果没有找到相应的class文件,他会抛出ClassNotFoundException异常。在版本1.2中,findSystemClass()方法使用系统类装载器类装载指定类型。任何Java虚拟机实现都必须保证fidnSystemClass()方法能够以这种方式调用启动类装载器(如果运行1.0或版本1.1),或者系统类装载器(如果运行版本1.2或以上)。
resolveClass()方法接受一个Class实例的引用作为参数,他将对该Class实例表示的类型执行连接动作。而前面提到的defineClass()方法则只负责装载。当defineClass()方法返回一个CLass实例时,也就表示指定的class文件已经被找到并装载到方法区了,但是却不一定被连接和初始化了。Java虚拟机必须保证ClassLoader类的resolveClass()方法能够让类装载器子系统执行连接动作。
关于Java虚拟机怎样执行装载、连接以及初始化动作,将在后续章节中阐述。
命名空间
每个类装载器都有自己的命名空间,其中维护着由它装载的类型。所以一个Java程序可以多次装载具有同一个全限定名的多个类型。这样一个类型的全限定名就不足以确定在一个Java程序可以多次装载具有同一个全限定名的多个类型。因此,当多个类装载器都装载了同名的类型时,为了唯一地标识该类型,还要在类型名称前面加上一个装载该类型(指出了他所位于的命名空间)的类装载器的标识。
java虚拟机中的命名空间,其实是解析过程的结果。对于每个被庄子啊的类型,Java虚拟机都会记录装载它的类装载器,当虚拟机解析一个类到另一个类的符号引用时,他需要被引用类的类装载器。
几点说明:
1. 自定义类装载器何时使用?
Java应用程序能够在运行时安装用户自定义的类装载器,这种类装载器能够使用自定义的方式来装载类,例如,从网络下载class文件,从数据库获取,甚至可以动态生成。尽管启动类装载器是虚拟机实现的本质部分,而用户自定义的类装载器不是;但是用户自定义的类装载器能够用java编写,能够被编译为class文件,能够被虚拟机装载,还能够像其他对象一样实例化。他们实际上只是运行中的java应用程序可以执行代码的一部分。至此应该明白自定义类装载器应该何时使用了。对于需要动态加载java文件,可以使用用户自定义类加载器。由于有自定义类装载器的存在,使得在运行时扩展java应用程序成为可能。
再多说两句,每一个类被装载的时候,Java虚拟机都件事这个类,看他到底是被启动类装载器还是被用户定义类装载器装载。当被装载的类引用了另外一个类时,虚拟机就会使用装载第一个类的类装载器装载被引用的类。
上图是Java类装载器的体系结构。
由于Java虚拟机采用这种方式进行类的装载,所以被装载的类默认情况下只能看到被同一个类装载器装载的别的类。通过这种方法,Java的体系结构允许在一个Java应用程序中建立多个命名空间。运行时的Java程序中的每个类装载器都有一个他自己的命名空间。
一个Java应用程序能够从同一个类或者多个类中实例化多个用户定义的类装载器。因此,需要多少个(或者多少种)用户自定义的类装载器,java应用程序就可以创建多少个(或多少种),被不同的类装载器装载的类存放在不同的命名空间中,他们不能互相访问,除非应用程序显示地允许这样做。当编写一个Java应用程序的时候,从不同源文件装载的类可以分割在不同的命名空间中。通过这种方法,就能够使用Java类装载器的体系结构来控制从不同源文件中装载的代码之间的相互影响,特别是能够阻止恶意代码获取访问和破坏善意代码的权限,可以看出Java类装载器的体系结构提供了对网络移动性的支持。
Web浏览器是一个动态扩展的例子,Web浏览器使用用户自定义的类装载器从网络上下载用于Java applet的class文件。web浏览器使用一个用来安装用户自定义类装载器的Java应用程序,这个用户定义的类装载器通常被称为Java applet类装载器,他知道如何向Http服务器请求class文件。Java applet可以作为动态扩展的例子,因为当浏览器遇到有Java applet的页面的时候,才决定是否需要下载class文件。
Web浏览器启动的Java应用程序通常为每个提供class文件的网络地址分步创建不同的用户自定义类装载器,因此,不同的用户自定义类装载器庄子不同来源的class文件。这就可以吧他们分别放置在Java主机应用程序的不同命名空间之中。由于不同来源的Java applet代码不会直接妨碍到从别的地方下载的class文件。
2.JVM运行时的ClassLoader介绍
JVM在运行时会产生三个ClassLoader:Bootstrap ClassLoader、Extension ClassLoader和AppClassLoader. 其中,Bootstrap是用C++编写的,我们在Java中看不到它,是null。它用来加载核心类库,在JVM源代码中这样写道: static const char classpathFormat[] = "%/lib/rt.jar:" "%/lib/i18n.jar:" "%/lib/sunrsasign.jar:" "%/lib/jsse.jar:" "%/lib/jce.jar:" "%/lib/charsets.jar:" "%/classes"; Extension ClassLoader用来加载扩展类,即/lib/ext中的类。 最后AppClassLoader才是加载Classpath的。 ClassLoader加载类用的是委托模型。即先让Parent类(而不是Super,不是继承关系)寻找,Parent找不到才自己找。 三者的关系为:AppClassLoader的Parent是ExtClassLoader,而ExtClassLoader的Parent为Bootstrap ClassLoader。 加载一个类时,首先BootStrap先进行寻找,找不到再由ExtClassLoader寻找,最后才是AppClassLoader。 为什么要设计的这么复杂呢?其中一个重要原因就是安全性。比如在Applet中,如果编写了一个java.lang.String类并具有破坏性。 假如不采用这种委托机制,就会将这个具有破坏性的String加载到了用户机器上,导致破坏用户安全。但采用这种委托机制则不会出现这种情况。 因为要加载java.lang.String类时,系统最终会由Bootstrap进行加载,这个具有破坏性的String永远没有机会加载。
评论
gc的工作原理迟早会写篇文章介绍下的,哈哈。敬请期待吧!!
发表评论
-
JVM Specification Third Edition --> Chapter 5 Loading,Linking and Initializing翻译
2011-08-30 14:18 0Chapter 5 Loading,Linking and I ... -
Java method invoke的指令简介
2011-08-29 14:45 11616方法调用相关的jvm子令集主要有一下四种: invok ... -
jdk提供的内存分析工具列表
2011-08-22 12:16 0jmap 倾向于分析对象信息 jhat 倾向于分析du ... -
J2EE企业架构性能关键点
2011-08-19 15:33 0硬件、操作系统的性能 1. 运算速度 --> C ... -
自用【链接贴】
2011-09-17 20:05 1647//------------------------- ... -
自己动手写写:GC何时触发?
2011-07-20 10:48 5098本文是基于Oracle的Hotspot ... -
浅谈设置JVM内存分配的几个妙招(转)
2011-07-08 18:57 1239一、设置JVM内存设置 1. 设置JVM内存的参数有 ... -
自己动手写写:Java序列化
2011-07-06 16:00 1413从以下几个方面来讨论这个问题 1、序列化是用来干什么的 ... -
自己动手写写:Java GC
2011-06-29 11:22 2748为什么要使用垃圾收集器? 类似类型为什么要收集一样(参 ... -
Java类型的生命周期简介
2011-06-28 18:19 1268这里要讲的是类型(Class) ... -
java class文件简介
2011-06-23 16:51 6209之前对Java虚拟机作了概述,接下来来讲一讲Java clas ... -
Java的数据类型
2011-06-21 23:33 1456Java数据类型 Java虚 ... -
自己动手写写:关于jvm的理解(3)
2011-06-17 15:08 5678上篇文章讲到了Heap(堆 ... -
自己动手写写:关于jvm的理解(2)
2011-06-16 22:58 2589上篇文章描述了Runtime Da ... -
自己动手写写:关于jvm的理解(1)
2011-06-16 17:45 7404Java虚拟机是什么 要理解jav ...
相关推荐
java类装载介绍,介绍了java装载类的先后顺序
类装载器学习一、类加载器的基本概念 类装载器学习一、类加载器的基本概念 类装载器学习一、类加载器的基本概念
在Java编程语言中,类装载器(ClassLoader)和命名空间是理解Java运行时环境的重要概念。它们共同确保了程序的正确性和安全性。类装载器负责将类文件加载到Java虚拟机(JVM)中,而命名空间则帮助组织和管理这些类,...
【浅析J2EE应用服务器的JAVA类装载器】 Java类装载器机制是Java语言灵活性的关键组成部分,尤其在J2EE应用服务器中扮演着重要角色。理解这一机制有助于开发者更好地部署和管理应用程序,解决可能出现的部署问题。 ...
### Java深度历险(2)--深入类装载器 #### 前言 在现代软件开发领域,特别是使用Java这样的高级编程语言时,“动态性”是一个非常重要的概念。它指的是程序能够在运行时根据需要加载、卸载或替换部分代码的能力。这...
类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一。它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java ...
所有JVM都内置了一个特殊的类装载器——根装载器(Bootstrap ClassLoader),它负责装载Java核心类库。当需要装载非设计时已知的类时,则需要使用用户自定义的类装载器。 #### 实例演示 以下是一个简单的示例,...
Java虚拟机类装载机制是Java运行环境的核心技术之一,它允许程序在运行时动态加载和使用类,极大地增强了软件的灵活性和可扩展性。本文主要探讨了类装载的原理、实现方式及其在实际应用中的作用。 首先,类装载的...
Java的JVM(Java Virtual Machine)类装载器是Java运行时系统的重要组成部分,负责在程序运行期间查找并加载类的二进制数据。理解类装载器的工作原理对于优化Java应用性能和实现动态加载类至关重要。 装载过程包括...
这个“java之jvm学习笔记五(实践写自己的类装载器)”很可能是对这一主题的详细探讨。 类装载器在Java中的主要职责是动态加载类到JVM中。Java的类装载器分为三个基本层次:启动类装载器(Bootstrap ClassLoader)、...
在Java中,类装载器 把一个类装入Java虚拟机中,要经过三个步骤来完成:装载、链接和初始化。其中链接又可以分成校验、准备和解析三步,除了解析外,其它步骤是严格按照顺序完成的。各个步骤的主要工作如下: * ...
Java虚拟机类装载机制是Java运行环境中的核心组成部分,它负责将类的字节码从磁盘、网络等不同来源加载到JVM中,并进行一系列处理以使类能够被正确地使用。类装载机制的目的是为了实现代码的动态加载和运行时的灵活...
Java 类装载过程是Java虚拟机(JVM)运行的核心机制之一,主要涉及到类从加载到初始化的完整生命周期。这一过程确保了程序的正确运行,并在安全性方面起到关键作用。以下是详细的解释: 1)装载(Loading): 在这...
装载问题-分支限界算法-java实现 装载问题 装载问题是一种经典的组合优化问题,目的是在有限的容量内装载尽可能多的物品,以达到最大化总重量或总价值。装载问题有多种变种,包括0/1背包问题、分支限界问题、动态...
1. **类装载器的层次结构**:Java的类装载器采用双亲委派模型,即当一个类装载器接到加载类的请求时,它首先会委托父类装载器去尝试加载,只有当父类装载器无法加载时,子类装载器才会尝试自己加载。这种模型保证了...
- 系统类装载器是JVM内置的,用于加载Java标准库的类。 理解类装载机制对于优化程序性能、实现动态加载、插件系统以及增强程序的灵活性具有重要意义。例如,通过自定义类装载器,开发者可以在运行时替换或添加新的...
在Java中,类装载器是分层的,由Bootstrap ClassLoader、Extension ClassLoader和App ClassLoader构成,它们遵循双亲委托模型。当一个类装载器收到加载类的请求时,它首先会委托给父类装载器,只有当父类装载器无法...
Java类的装载过程主要由类加载器(ClassLoader)来完成,这是一个关键组件,它负责查找、加载和初始化类。Java类加载器分为系统类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用...