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虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类.实现这 ...
随机推荐
- 将Apache添加为Linux的服务 实现自启动(转)
在Linux下用源代码方式编译安装完Apache后,启动关闭Apache可以通过如下命令实现: /app/apache2.2.14/bin/apachectl start | stop | resta ...
- Difference between Tomcat's extraResourcePaths and aliases to access an external directory--转
Question: Simple question: In Tomcat7, what's the difference between using extraResourcePaths and al ...
- uploadify上传大文件时出现404错误
出现这个错误的话一般是IIs限制了文件大小.IIS7下的默认设置限制了上传大小.这个时候Web.Config中的大小设置也就失效了.具体步骤:1.打开IIS管理器,找到Default Web Site ...
- ASP.NET-FineUI开发实践-4
最近实在没时间研究东西,FineUI一直也没进一步实践,但是还是很想学点东西,所以找了个课题研究了下,在论坛里看见了又下角的提醒,自己想了想做了一个,我不是大神,接触EXTJS很少,就是用到哪看哪,没 ...
- 数据库操作封装类 DBHelper.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Co ...
- SharePoint中获取当前登录的用户名几种方式
第一种方法: System.Web.HttpContext.Current.User.Identity.Name.ToString();或者: SPContext.Current.Site.OpenW ...
- Linq使用GroupBy筛选数据
StringBuilder sb = new StringBuilder(); List<IGrouping<string, modle>> listRepeat = mode ...
- memcache和数据库的使用技巧
1.加速无数据的访问速度毋庸置疑取数据先去取下memcache里的数据,如果没有再去数据库取数据但这样如果我取100次都是没有的那么我得去数据库去取100次 如果还是重复的...那么效率就不高了 解决 ...
- Windows 7 64位下解决不能创建Django项目问题
把djingo-admin.py的全路径写出来 在cmd命令行下直接输入python C:\Python27\Scripts\django-admin.py startproject site(sit ...
- 认识cocos2d-x jsbinding
近年来HTML5风起云涌,特别在移动端已经被更多的人熟识.H5跨平台,在线更新等特性,被人们津津乐道.然后就出现了各种H5的框架,甚至多达100种,真是让开发者眼花缭乱,笔者作为一个从事H5游戏开发一 ...