Tomcat类加载器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { Class clazz = null ; // (0) Check our previously loaded local class cache clazz = findLoadedClass0(name); if (clazz != null ) { if (log.isDebugEnabled()) log.debug( " Returning class from cache" ); if (resolve) resolveClass(clazz); return (clazz); } // (0.1) Check our previously loaded class cache clazz = findLoadedClass(name); if (clazz != null ) { if (log.isDebugEnabled()) log.debug( " Returning class from cache" ); if (resolve) resolveClass(clazz); return (clazz); } // (0.2) Try loading the class with the system class loader, to prevent // the webapp from overriding J2SE classes try { clazz = system.loadClass(name); if (clazz != null ) { if (resolve) resolveClass(clazz); return (clazz); } } catch (ClassNotFoundException e) { // Ignore } boolean delegateLoad = delegate || filter(name); // (1) Delegate to our parent if requested if (delegateLoad) { if (log.isDebugEnabled()) log.debug( " Delegating to parent classloader1 " + parent); ClassLoader loader = parent; if (loader == null ) loader = system; try { clazz = loader.loadClass(name); if (clazz != null ) { if (log.isDebugEnabled()) log.debug( " Loading class from parent" ); if (resolve) resolveClass(clazz); return (clazz); } } catch (ClassNotFoundException e) { ; } } // (2) Search local repositories if (log.isDebugEnabled()) log.debug( " Searching local repositories" ); try { clazz = findClass(name); if (clazz != null ) { if (log.isDebugEnabled()) log.debug( " Loading class from local repository" ); if (resolve) resolveClass(clazz); return (clazz); } } catch (ClassNotFoundException e) { ; } // (3) Delegate to parent unconditionally if (!delegateLoad) { if (log.isDebugEnabled()) log.debug( " Delegating to parent classloader at end: " + parent); ClassLoader loader = parent; if (loader == null ) loader = system; try { clazz = loader.loadClass(name); if (clazz != null ) { if (log.isDebugEnabled()) log.debug( " Loading class from parent" ); if (resolve) resolveClass(clazz); return (clazz); } } catch (ClassNotFoundException e) { ; } } throw new ClassNotFoundException(name); } |
如下是Tomcat6的类加载器结果图
|
ExtensionClassLoader(对于Sun JVM,是sun.misc.Launcher$ExtClassLoader)
|
SystemClassLoader(对于Sun JVM,是sun.misc.Launcher$AppClassLoader)
|
CommonClassLoader(对于Tomcat 6,是org.apache.catalina.loader.StandardClassLoader)
/ \
CatalinaClassLoader SharedClassLoader
|
org.apache.catalina.loader.WebappClassLoader
|
org.apache.jasper.servlet.JasperLoader
- CommonClassLoader:
加载的类目录通过{tomcat}/conf/catalina.properties中的common.loader指定,以
SystemClassLoader为parent(目前默认定义是
common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar) - CatalinaClassLoader
:加载的类目录通过{tomcat}/conf/catalina.properties中server.loader指定,以
CommonClassLoader为parent,如果server.loader配置为空,则ServerClassLoader
与CommonClassLoader是同一个(默认server.loader配置为空) - SharedClassLoader:加载
的类目录通过{tomcat}/conf/catalina.properties中share.loader指定,以
CommonClassLoader为parent,如果server.loader配置为空,则CatalinaClassLoader
与CommonClassLoader是同一个(默认share.loader配置为空) - WebappClassLoader:每个
Context一个WebappClassLoader实例,负责加载context的/WEB-INF/lib和/WEB-INF/classes目
录,context间的隔离就是通过不同的WebappClassLoader来做到的。由于类定义一旦加载就不可改变,因此要实现tomcat的
context的reload功能,实际上是通过新建一个新的WebappClassLoader来做的,因此reload的做法实际上代价是很高昂的,
需要注意的是,JVM内存的Perm区是只吃不拉的,因此抛弃掉的WebappClassLoader加载的类并不会被JVM释放,因此tomcat的
reload功能如果应用定义的类比较多的话,reload几次就OutOfPermSpace异常了。(关于JVM的内存管理,可以参见之前的文章 ,后续对这一块重新做总结) - JasperLoader:
每个JSP一个JasperLoader实例,与WebappClassLoader做法类似,JSP支持修改生效是通过丢弃旧的
JasperLoader,建一个新的JasperLoader来做到的,同样的,存在轻微的PermSpace的内存泄露的情况
Tomcat类加载器的更多相关文章
- java类加载器-Tomcat类加载器
在上文中,已经介绍了系统类加载器以及类加载器的相关机制,还自定制类加载器的方式.接下来就以tomcat6为例看看tomat是如何使用自定制类加载器的.(本介绍是基于tomcat6.0.41,不同版本可 ...
- Tomcat类加载器机制
Tomcat为什么需要定制自己的ClassLoader: 1.定制特定的规则:隔离webapp,安全考虑,reload热插拔 2.缓存类 3.事先加载 要说Tomcat的Classloader机制,我 ...
- Tomcat类加载器破坏双亲委派
转载:https://blog.csdn.net/qq_38182963/article/details/78660779 http://www.cnblogs.com/aspirant/p/8991 ...
- Tomcat类加载器体系结构
<深入理解java虚拟机>——Tomcat类加载器体系结构 标签: java / 虚拟机 / tomcat Tomcat 等主流Web服务器为了实现下面的基本功能,都实现了不止一个自定义的 ...
- Tomcat 类加载器的实现
Tomcat 内部定义了多个 ClassLoader,以便应用和容器访问不同存储库中的类和资源,同时达到应用间类隔离的目的.本文首发于公众号:顿悟源码. 1. Java 类加载机制 类加载就是把编译生 ...
- 深入理解JVM虚拟机7:JNDI,OSGI,Tomcat类加载器实现
打破双亲委派模型 JNDI JNDI 的理解 JNDI是 Java 命名与文件夹接口(Java Naming and Directory Interface),在J2EE规范中是重要的规范之中的一 ...
- (转)《深入理解java虚拟机》学习笔记8——Tomcat类加载器体系结构
Tomcat 等主流Web服务器为了实现下面的基本功能,都实现了不止一个自定义的类加载器: (1).部署在同一个服务器上的两个web应用程序所使用的java类库可以相互隔离. (2).部署在同一个服务 ...
- tomcat: 类加载器
一.tomcat是个web容器,要解决以下问题 1. 一个web容器可能要部署两个或者多个应用程序,不同的应用程序,可能会依赖同一个第三方类库的不同版本,因此要保证每一个应用程序的类库都是独立.相互隔 ...
- Java类加载机制与Tomcat类加载器架构
Java类加载机制 类加载器 虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类.实现这 ...
随机推荐
- lamp安装指南(转)
主要软件包, 1. httpd-2.2.6.tar.gz 2. mysql-5.0.45-linux-i686-glibc23.tar.gz ( 这个版本是已编译好的压缩包,解压后稍做配置即可使用 ) ...
- C语言判断文件是否存在
用函数access,头文件是io.h,原型: int access(const char *filename, int amode); amode参数为0时表示检查文件的 ...
- MegaCLI SAS RAID Management Tool
MegaCLI SAS RAID Management Tool Ver 8.04.08 July 05, 2012 (c)Copyright 2011, LSI Corporation, A ...
- 判断两条直线的位置关系 POJ 1269 Intersecting Lines
两条直线可能有三种关系:1.共线 2.平行(不包括共线) 3.相交. 那给定两条直线怎么判断他们的位置关系呢.还是用到向量的叉积 例题:POJ 1269 题意:这道题是给定四个点p1, ...
- sessionstorage,localstorage和cookie之间的区别
sessionStorage 和 localStorage 是HTML5 Web Storage API 提供的,可以方便的在web请求之间保存数据.有了本地数据,就可以避免数据在浏览器和服务器间不必 ...
- JS相关链接
给开发者提供的 35 款 JavaScript 图形图表库: http://news.cnblogs.com/n/201518/ 主题:[前端必看]JavaScript推荐资料合集: http://w ...
- Linux下批量替换文件内容方法
1:查找find . -type f -name "*.html"|xargs grep ‘yourstring’ 2:查找并替换find -name '要查找的文件名' | xa ...
- 如何打开Windows Server 2003 内存寻址扩展
本文介绍了如何在系统内存大于4G的情况下,让windows2003 Advanced Server支持大内存的方法: 由于Windows2003 32bit是32位操作系统,当服务器配备内存高达4G时 ...
- 工作流activiti-03数据查询(流程定义 流程实例 代办任务) 以及个人小练习
在做数据查询的时候通过调用api来查询数据是相当的简单 对分页也进行了封装listPage(0, 4) ;listPage:分页查询 0:表示起始位置,4:表示查询长度 但是公司的框架封装了分页数据 ...
- How To Learn English Very Fast
How do you learn English very fast? Every week, I get emails about this topic. Typically, someone ...