转自:http://blog.csdn.net/codolio/article/details/5027423

加载类是运行程序的基础,了解Java和Tomcat的类加载机制对更有效地开发、调试Web应用程序有一定的积极作用。本文简单介绍Java和Tomcat的类加载机制,希望对大家有所帮助。

  • JDK/JRE文件结构

在安装JDK后,其典型的目录层次如下所示(JDK 1.6.0):

主要的目录和JAR简述如下:

  • <JAVA_HOME>/bin: 包含在JDK中的开发工具的可执行文件,一般而言,PATH环境变量应包含该目录。
  • <JAVA_HOME>/lib: 开发工具使用的文件,其中包括(1)tools.jar:该JAR包包含支持JDK中工具类和实用类的非核心类。同时也包含(2)dt.jar:BeanInfo使用的设计时(DesignTime)归档文件,该JAR包告诉IDE如何显示Java组件和如何让开发者定制它们。其中主要包含Swing的相关类。
  • <JAVA_HOME>/jre/lib:包含Java运行时环境使用的核心类、属性设置和资源文件等。例如:(1)rt.jar:引导类(组成Java平台核心API的运行时类);(2)charsets.jar:字符转换类。

在一个典型的Web应用环境中,在设置CLASSPATH环境变量是,通常需要包含以下条目:

  • .:为当前目录;
  • <JAVA_HOME>/lib/tools.jar。

注:在使用Tomcat作为Servlet/JSP容器的Web环境中,Tomcat在启动过程中清除了原有CLASSPATH的内容,并对其进行了重新定义。细节见下文。

  • Java类加载机制

Java启动器(java)初始化Java虚拟机。虚拟机按照如下顺序搜索加载类:

  1. 引导类:组成Java平台的类,包括rt.jar和一些别的重要的jar文件;
  2. 扩展类:使用Java扩展机制的类,这些类捆绑成JAR文件,并被放置在扩展目录中;每一个在jre/lib/ext扩展目录下的JAR文件均被设定为一个扩展并使用Java扩展架构加载;
  3. 用户类:由开发者定义的类和没有利用扩展机制的第三方类,这些类的位置由用户指定,一般通过使用-classpath命令行选项或者使用CLASSPATH环境变量来指定其位置。

与之相对应,自从J2SE 1.2规范起,JVM就已经利用了三种不同的类加载器:

  • 引导类(Bootstrap)加载器(也称为初始类加载器);
  • 扩展类加载器;
  • 系统类加载器。

这些类加载器是有层次的,系统类加载器位于底层,而引导类加载器位于上层,它们之间的关系为父-子关系。

  • 引导类加载器:引导类加载器用于JVM加载那些它运行所需的Java类。实际上,引导类加载器负责加载所有核心的Java类(如java.lang.*和java.io.*)。一般各种JVM厂商(包括Sun)使用本地代码实现引导类加载器。
  • 扩展类加载器:Java 1.2引入了标准扩展机制。可以将JAR文件放置在标准扩展目录,JVM将能自动地找到它们。扩展类加载器负责加载一个或者多个扩展目录中的所有类。一般情况下,只要安装了Java运行环境(JRE),那么扩展目录为<JRE>/lib/ext。扩展类加载器可以不是独立的类加载器,一些实现也许甚至允许引导类加载器从扩展目录加载类。
  • 系统类加载器:系统类加载器在CLASSPATH环境变量指定的JAR文件中查找自己的类,或通过-classpath命令行选项传递该类,如果没有指定,则默认使用当前目录。系统加载器也用于加载应用程序的entry point类(即含有main()方法的类),对于那些其他任何没有涵盖在以上两类加载器中的类,都默认使用系统类加载器。
  • 委派模型:JVM通过利用委派模型知道将使用哪个类加载器。Java JDK 1.2以后的版本,无论类加载器何时收到加载类的请求。在一个类加载器试图加载一个请求的类之前,它委派该加载请求到其父类类加载器,直到引导类加载器。如果父类加载器成功加载所请求的类,那么就返回作为结果的类对象,只有当父类加载器未能加载该类的情况下,原始的类加载器才尝试装载该类。

注:类加载器的更多行为:

  • 懒散加载:上述类加载器并没有预加载在搜索该路径中的所有类。相反它按要求加载类。这样的行为称为懒散加载。
  • 类缓存:标准的Java SE类加载器可以按要求查找类,但一旦某个类被加载到类加载器中,它将维持加载(缓存)一段时间。不过,JVM垃圾收集器可以回收这些Class对象。
  • 独立的命名空间:为每个类加载器分配了唯一的命名空间。
  • Apache Tomcat 5.5 Servlet/JSP类加载机制:

同其它服务器应用程序类似,Tomcat 5安装了多种类加载器(即,实现了java.lang.ClassLoader接口的类),来允许容器的不同部分和运行在容器中的Web应用程序来访问不同可用类和资源的库。

当Tomcat 5启动时,它创建了一套类加载器,这些加载器组织成如下的父子关系,其中父类加载器位于子类加载器之上(Tomcat 6.0版本的类加载器层次结构发生了变化):

加载器定义如下:

  • Bootstrap:该加载器包含由JVM提供的基本的运行时类,加上放置在系统扩展目录(<JAVA_HOME/jre/lib/ext>)的JAR文件中的类。注:一些JVAM将该加载器实现为一个以上的类加载器,或者它完全不可见;
  • System:系统加载器,该加载器通常使用CLASSPATH环境变量来初始化。但是标准的Tomcat 5启动脚本(<CATALINA_HOME>/bin/catalina.sh或者<CATALINA_HOME>/bin/catalina.bat>)完全忽略了CLASSPATH环境变量的内容,并使用下述库来构建System类加载器。如下:

从上图可以看出,Tomcat使用的CLASSPATH并非我们先前配置的目录。

<CATALINA_HOME>/bin/bootstrap.jar:包含初始化Tomcat 5服务器的main()方法和它所依赖的类加载器实现;

<JAVA_HOME>/lib/tools.jar:包含" javac "编译器用来将JSP页面转化为servlet类;

       <CATALINA_HOME>/bin/commons-logging-api-x.y.z.jar:包含commons logging API;

       <CATALINA_HOME>/bin/commons-daemon.jar:包含commons daemon API;

       jmx.jar :包含JMX 1.2实现。

  • Common:该类加载器包含一些对Tomcat内部类和web应用可见的额外类。其中包括(1)jasper-compiler.jar:JSP 2.0编译器(2)jsp-api.jar:JSP 2.0 API(3)servlet-api.jar:servlet 2.4 API等等。
  • Catalina:该加载器初始化用来包含实现Tomcat 5本身所需要所有类和资源;
  • Shared:在所有的web应用程序间共享的类和资源;
  • WebappX:为每个部署在单个Tomcat 5实例上的Web应用创建的类加载器。加载/WEB-INF/classes和WEB-INF/lib下的类和资源。

值得注意的是,Web应用程序类加载器行为与默认的Java 2委派模型不同。当一个加载类的请求被WebappX类加载器处理时,类加载器将首先查看本地库,而非在查看前就委派,但是也有例外,作为JRE基本类一部分的类不能被覆盖,但是对与一些类,可以使用J2SE 1.4的Endorsed Standards Override机制。最后,任何包含servlet API的JAR包都将被该类加载器忽略。Tomcat 5所有其它的类加载器遵循常用的委派模式。具体细节请参见Tomcat
5的参考文档。

Java和Tomcat类加载机制的更多相关文章

  1. Tomcat类加载机制和JAVA类加载机制的比较

    图解Tomcat类加载机制    说到本篇的tomcat类加载机制,不得不说翻译学习tomcat的初衷.    之前实习的时候学习javaMelody的源码,但是它是一个Maven的项目,与我们自己的 ...

  2. 图解Tomcat类加载机制

    说到本篇的tomcat类加载机制,不得不说翻译学习tomcat的初衷. 之前实习的时候学习javaMelody的源码,但是它是一个Maven的项目,与我们自己的web项目整合后无法直接断点调试.后来同 ...

  3. Tomcat系列(7)——Tomcat类加载机制

    1. 核心部分 1. 类加载器: 通过一个类的全限定名来获取描述此类的二进制字节流. 对于任意一个类,都需要由加载他的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性,每一个类加载器,都拥有一 ...

  4. 图解Tomcat类加载机制(阿里面试题)

    Tomcat的类加载机制是违反了双亲委托原则的,对于一些未加载的非基础类(Object,String等),各个web应用自己的类加载器(WebAppClassLoader)会优先加载,加载不到时再交给 ...

  5. 《转载》图解Tomcat类加载机制

    本文转载自http://www.cnblogs.com/xing901022/p/4574961.html 说到本篇的tomcat类加载机制,不得不说翻译学习tomcat的初衷. 之前实习的时候学习j ...

  6. Tomcat类加载机制触发的Too many open files问题分析(转)

    https://blog.csdn.net/ctrip_tech/article/details/53337137 说起Too many open files这个报错,想必大家一定不陌生.在Linux ...

  7. 图解JVM和Tomcat类加载机制

    说到本篇的tomcat类加载机制,不得不说翻译学习tomcat的初衷. 之前实习的时候学习javaMelody的源码,但是它是一个Maven的项目,与我们自己的web项目整合后无法直接断点调试.后来同 ...

  8. java 虚拟机的类加载机制

    Java 虚拟机的类加载机制 关于类加载机制: ​ 虚拟机把描述类的数据从Class 文件加载到内存,并对数据进行效验.转换解析和初始化,最终 形成可以被虚拟机直接使用的Java 类型,就是虚拟机的类 ...

  9. Java基础:类加载机制

    之前的<java基础:内存模型>当中,我们大体了解了在java当中,不同类型的信息,都存放于java当中哪个部位当中,那么有了对于堆.栈.方法区.的基本理解以后,今天我们来好好剖析一下,j ...

随机推荐

  1. echo和print语句

    在php中,有两种基本的输出方法:echo  和  print echo 和 print 之间的差异: echo——能够输出一个以上的字符串,无返回值 print——只能输出一个字符串,并始终返回值为 ...

  2. 服务端生成word并压缩打包下载

    所需工具 phpwrod 库 php_zip 扩展 下载phpword库,放到类加载路径. 安装php_zip扩展 下载地址 http://pecl.php.net/package/zip linux ...

  3. 方便mac os 10.9系统中phpstorm配置php运行环境

    自己安装php,不用mac安装,这样就有php开发环境了. 安装很简单,直接运行一个命令, 需要几分钟,请慢慢等待. curl -s http://php-osx.liip.ch/install.sh ...

  4. iBatis系列之三

    iBatis和Hibernate最大差别就是在于iBatis没有严格的和具体的表做关联:而是将结果集和DAO做关联. iBatis的SqlConfig.xml配置一个properties文件,其实可以 ...

  5. 《Linux命令行大全》系列(二、导航)

    文件系统的导航,是一个不断访问树形结构中节点的过程. 文件系统树 Linux只有一个倒立的文件系统树 不同设备可以挂载到这同一个树上 文件和子目录是此树的组成部分,最顶层的即根目录 目录 根据树节点间 ...

  6. 如何创建一个自定义jQuery插件

    简介 jQuery 库是专为加快 JavaScript 开发速度而设计的.通过简化编写 JavaScript 的方式,减少代码量.使用 jQuery 库时,您可能会发现您经常为一些常用函数重写相同的代 ...

  7. Ubuntu 安装基础教程

    转自:http://teliute.org/linux/Ubsetup/index.html 1.进入 live cd 桌面  1)设置好启动后,断开网络,然后重启动计算机,可以用硬盘启动,也可以刻成 ...

  8. 心愿:做一个精简版MFC

    我觉得自己有能力看懂MFC的C++代码和总体流程,但是由于MFC混杂了太多的东西,比如OLE等等不必要的东西,又做了无数的ASSERT判断,影响整体流程的理解.因此我要做一个精简版的MFC,而且能用它 ...

  9. Xamarin 开发常见问题

    原文:Xamarin 开发常见问题 Verify the project is selected to be deployed in the Solution Configuration Manage ...

  10. Android Training精要(六)如何防止Bitmap对象出现OOM

    1.使用AsyncTask異步加載bitmap圖片避免OOM: class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> ...