Tomcat笔记3(server启动分析)

Tomcat的启动是从Bootstrap类当中的main方法开始的,在bat文件的启动命令脚本最终echo之后,其中的输出是org.apache.catalina.startup.Bootstrap.main start,开始发动tomcat。
进入main函数中分析其流程:
public static void main(String args[]) {

if (daemon == null) {
// Don't set daemon until init() has completed
Bootstrap bootstrap = new Bootstrap();
try {
bootstrap.init();
} catch (Throwable t) {
t.printStackTrace();
return;
}
daemon = bootstrap;
}

try {
String command = "start";
if (args.length > 0) {
command = args[args.length - 1];
}

if (command.equals("startd")) {
args[args.length - 1] = "start";
daemon.load(args);
daemon.start();
} else if (command.equals("stopd")) {
args[args.length - 1] = "stop";
daemon.stop();
} else if (command.equals("start")) {
daemon.setAwait(true);
daemon.load(args);
daemon.start();
} else if (command.equals("stop")) {
daemon.stopServer(args);
} else {
log.warn("Bootstrap: command \"" + command + "\" does not exist.");
}
} catch (Throwable t) {
t.printStackTrace();
}

}

实例化Bootstrap之后,进入其init()方法当中,
    /**
* Initialize daemon.
*/
public void init()
throws Exception
{

// Set Catalina path
setCatalinaHome();
setCatalinaBase();

initClassLoaders();

Thread.currentThread().setContextClassLoader(catalinaLoader);

SecurityClassLoad.securityClassLoad(catalinaLoader);

// Load our startup class and call its process() method
if (log.isDebugEnabled())
log.debug("Loading startup class");
Class<?> startupClass =
catalinaLoader.loadClass
("org.apache.catalina.startup.Catalina");
Object startupInstance = startupClass.newInstance();

// Set the shared extensions class loader
if (log.isDebugEnabled())
log.debug("Setting startup class properties");
String methodName = "setParentClassLoader";
Class<?> paramTypes[] = new Class[1];
paramTypes[0] = Class.forName("java.lang.ClassLoader");
Object paramValues[] = new Object[1];
paramValues[0] = sharedLoader;
Method method =
startupInstance.getClass().getMethod(methodName, paramTypes);
method.invoke(startupInstance, paramValues);

catalinaDaemon = startupInstance;

}

在init方法当中,首先初始化CatalinaHome和CatalinaBase路径,如果这两个路径都未被设定,则默认设置成当前tomcat的工作路径。
以setCatalinaHome()方法为例:
    /**
* Set the <code>catalina.home</code> System property to the current
* working directory if it has not been set.
*/
private void setCatalinaHome() {

if (System.getProperty("catalina.home") != null)
return;
File bootstrapJar =
new File(System.getProperty("user.dir"), "bootstrap.jar");
if (bootstrapJar.exists()) {
try {
System.setProperty
("catalina.home",
(new File(System.getProperty("user.dir"), ".."))
.getCanonicalPath());
} catch (Exception e) {
// Ignore
System.setProperty("catalina.home",
System.getProperty("user.dir"));
}
} else {
System.setProperty("catalina.home",
System.getProperty("user.dir"));
}

}

其中System.getProperty当中的catalina.home参数是在启动tomcat的bat文件时,我们设定好的参数,在catalina.bat文件当中echo了这么一段命令:
echo %_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %JPDA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Djava.security.manager -Djava.security.policy=="%SECURITY_POLICY_FILE%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% > command.txt

其中设定了catalina.home和catalina.base路径。
以上步骤获取了系统工作路径,接下来进行类加载器的初始化(setup),initClassLoaders(),方法内容如下:
[code] private void initClassLoaders() {
try {
commonLoader = createClassLoader("common", null);
if( commonLoader == null ) {
// no config file, default to this loader - we might be in a 'single' env.
commonLoader=this.getClass().getClassLoader();
}
catalinaLoader = createClassLoader("server", commonLoader);
sharedLoader = createClassLoader("shared", commonLoader);
} catch (Throwable t) {
log.error("Class loader creation threw exception", t);
System.exit(1);
}
}[/code]
以上代码将分别加载Tomcat的三种包:common,server,shared。分别对应catalina.properties文件中:
[code]common.loader=${catalina.home}/lib,${catalina.home}/lib/*.jar[/code]
[code]server.loader=[/code]
[code]shared.loader=[/code]
即为以上路径下面对应的jar包设置ClassLoaders。

下面继续看tomcat的类加载体系:

首先,涉及到JVM启动时类的加载机制,在OS为JVM进程分配内存空间(可以通过JVM启动参数手工设定)之后,程序入口点位于BootStrap类的main方法,在启动这个JavaApp之前首先实例化一个JVM的实例(而随着这个Java app的终止JVM实例也自动消亡),在一个JVM启动之后,其体系结构大致如下:

[img]http://dl.iteye.com/upload/attachment/369558/6ee3b90c-0966-3963-a032-6b28c2aadcbe.jpg[/img]

三个模块:
Class Loader System
Runtime Data Area
Execution Engine

其中Runtime Data Area 包括5种区域:
Heap & Method Area;
JavaStack & Native Method Stack;
Program Counter
以Bootstrap类启动为例,在JVM启动时将之载入内存的具体流程如下:
路径:org.apache.catalina.startup.Bootstrap,启动之前将Bootstrap类对应的Class文件当中的类型信息提取出来,load到JVM的Method Area当中,这也是被称作RTTI(Run-Time Type Infomation)用来保存运行时类型信息的一种方式。而且,这个Method Area是多线程共享的,所以当存在两个线程需要同时读取一个类的类型信息时,如果该类还没有被载入,则只能由其中一个线程先去将之load进来,另一线只有先等待了。
Method Area的具体内容:
Type Information
The Constant Pool
Field Information
Method Information Class Variables
A Reference to Class ClassLoader
A Reference to Class Class
Method Tables

之后,读取代码当中的静态初始化内容:
[code]
private static final Log log = LogFactory.getLog(Bootstrap.class);
protected static final String CATALINA_HOME_TOKEN = "${catalina.home}";
protected static final String CATALINA_BASE_TOKEN = "${catalina.base}";
private static Bootstrap daemon = null;
......
[/code]
对于第一行代码创建log对象,会在heap当中的Method Area存放当前log对应Class的Type Infomation,之后在线程Stack当中创建log引用(做为Log对象的reference);
在创建String类型时,如果采用上面所述的方式进行,将string的内容存放与heap中Method Area的常量池当中。之后进行对象创建时,首先判定如果当前Method Area当中不包含该类的类型信息,Load该类对应的Class文件,根据Method Area当中的类型信息计算当前对象的所需内存情况,在Heap当中为止分配内存空间,并将该对象的引用压倒栈中。
整个过程中,程序计数器为当前线程所独享,被用于定位下一执行指令的位置。
其中Heap和其中的Method Area是多线程之间共享的,而Java Stack/Program Counter是当前线程独享的,本地方法栈Native Stack是当程序中用到的本地方法时使用的,当JVM调用本地方法时,它就进入了一个不受虚拟机限制的空间,这时可能会产生JVM无法控制的内存问题:
Native Heap OutOfMemory!
另外提一下,在JVM当中压栈和出栈都是以帧为单位的(栈是跟着线程走的,有线程就有栈),每一帧包含的信息包括:

[img]http://dl.iteye.com/upload/attachment/369778/beaf122f-84c0-3b5f-9f92-1eb1563b0a9a.png[/img]

在这个图当中stack frame2对应的方法A被先调用,压栈之后,在其中调用stack frame2对应B方法,frame2被压栈。可以看出在Java 当中,栈并不是跟着方法走的,只是存储线程相关信息的地方,在方法调用时不会新产生stack,当然线程间的调用除外。

JVM在是否通过反射显示加载上将加载分为所谓的两种:显式加载和隐式加载;
从是否及时加载分成两种:pre-loading和lazy-loading。

而ClassLoader本身也有四种类型:BootstrapClassLoader,ExtensionClassLoader,AppClassLoader,URLClassLoader.分别针对一种加载场景,不过可以使用不同的ClassLoader加载一个相同Class,但是该Class对象的内容在启动JVM时通过pre-loading的方式加载系统的基本类库,其顺序大致如下:
BootstrapClassLoader
|
ExtensionClassLoader
|
AppClassLoader
通过New A().getClass().getClassLoader().toString()测试得到:
[code]
[Opened C:\Program Files\Java\jre6\lib\resources.jar]
[Opened C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Object from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.Serializable from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Comparable from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.CharSequence from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.String from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.reflect.GenericDeclaration from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.reflect.Type from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.reflect.AnnotatedElement from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Class from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Cloneable from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ClassLoader from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.System from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Throwable from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Error from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ThreadDeath from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Exception from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.RuntimeException from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.ProtectionDomain from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.AccessControlContext from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ClassNotFoundException from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.LinkageError from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.NoClassDefFoundError from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ClassCastException from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ArrayStoreException from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.VirtualMachineError from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.OutOfMemoryError from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.StackOverflowError from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.IllegalMonitorStateException from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ref.Reference from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ref.SoftReference from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ref.WeakReference from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ref.FinalReference from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ref.PhantomReference from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ref.Finalizer from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Runnable from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Thread from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Thread$UncaughtExceptionHandler from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ThreadGroup from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Map from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Dictionary from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Hashtable from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Properties from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.reflect.AccessibleObject from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.reflect.Member from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.reflect.Field from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.reflect.Method from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.reflect.Constructor from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.reflect.MagicAccessorImpl from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.reflect.MethodAccessor from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.reflect.MethodAccessorImpl from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.reflect.ConstructorAccessor from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.reflect.ConstructorAccessorImpl from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.reflect.DelegatingClassLoader from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.reflect.ConstantPool from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.reflect.FieldAccessor from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.reflect.FieldAccessorImpl from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.reflect.UnsafeFieldAccessorImpl from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.reflect.UnsafeStaticFieldAccessorImpl from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Appendable from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.AbstractStringBuilder from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.StringBuffer from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.StringBuilder from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.StackTraceElement from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.nio.Buffer from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.AtomicLong from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.AtomicLongCSImpl from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Boolean from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Character from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Number from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Float from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Double from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Byte from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Short from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Integer from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Long from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.NullPointerException from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ArithmeticException from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.ObjectStreamField from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Comparator from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.String$CaseInsensitiveComparator from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.Guard from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.Permission from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.BasicPermission from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.RuntimePermission from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.AbstractMap from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.SoftCache from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ref.ReferenceQueue from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ref.ReferenceQueue$Null from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ref.ReferenceQueue$Lock from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.HashMap from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Map$Entry from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.HashMap$Entry from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.AccessController from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.reflect.ReflectPermission from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.PrivilegedAction from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.reflect.ReflectionFactory$GetReflectionFactoryAction from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Iterable from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Collection from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.List from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.RandomAccess from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.AbstractCollection from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.AbstractList from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Vector from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Stack from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.reflect.ReflectionFactory from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ref.Reference$Lock from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ref.Reference$ReferenceHandler from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ref.Finalizer$FinalizerThread from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Enumeration from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Hashtable$EmptyEnumerator from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Iterator from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Hashtable$EmptyIterator from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Hashtable$Entry from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.nio.charset.Charset from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.nio.charset.spi.CharsetProvider from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.nio.cs.FastCharsetProvider from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.nio.cs.StandardCharsets from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.util.PreHashedMap from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.nio.cs.StandardCharsets$Aliases from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.nio.cs.StandardCharsets$Classes from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.nio.cs.StandardCharsets$Cache from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ThreadLocal from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.concurrent.atomic.AtomicInteger from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.Unsafe from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.IncompatibleClassChangeError from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.NoSuchMethodError from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.reflect.Reflection from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Collections from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Set from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.AbstractSet from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Collections$EmptySet from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Collections$EmptyList from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Collections$EmptyMap from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Collections$ReverseComparator from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Collections$SynchronizedMap from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Class$3 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.reflect.Modifier from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.reflect.LangReflectAccess from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.reflect.ReflectAccess from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.StringValue from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Arrays from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Math from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.nio.charset.Charset$3 from C:\Program Files\Java\jre6\lib\rt.jar]
[Opened C:\Program Files\Java\jre6\lib\jsse.jar]
[Opened C:\Program Files\Java\jre6\lib\jce.jar]
[Opened C:\Program Files\Java\jre6\lib\charsets.jar]
[Loaded sun.nio.cs.AbstractCharsetProvider from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.nio.cs.ext.ExtendedCharsets from C:\Program Files\Java\jre6\lib\charsets.jar]
[Loaded java.lang.Class$1 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.reflect.ReflectionFactory$1 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.reflect.NativeConstructorAccessorImpl from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.reflect.DelegatingConstructorAccessorImpl from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.SortedMap from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.NavigableMap from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.TreeMap from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.ASCIICaseInsensitiveComparator from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.TreeMap$Entry from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.VM from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.nio.cs.ext.GB18030 from C:\Program Files\Java\jre6\lib\charsets.jar]
[Loaded java.lang.StringCoding from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ThreadLocal$ThreadLocalMap from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ThreadLocal$ThreadLocalMap$Entry from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.StringCoding$StringDecoder from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.nio.charset.CharsetDecoder from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.nio.cs.ext.GB18030$Decoder from C:\Program Files\Java\jre6\lib\charsets.jar]
[Loaded java.nio.charset.CodingErrorAction from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.nio.ByteBuffer from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.nio.HeapByteBuffer from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.nio.Bits from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.nio.ByteOrder from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Readable from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.nio.CharBuffer from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.nio.HeapCharBuffer from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.nio.charset.CoderResult from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.nio.charset.CoderResult$Cache from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.nio.charset.CoderResult$1 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.nio.charset.CoderResult$2 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.Version from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.JavaLangAccess from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.System$2 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.SharedSecrets from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Runtime from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.File from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.FileSystem from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.Win32FileSystem from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.WinNTFileSystem from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.ExpiringCache from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.LinkedHashMap from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.ExpiringCache$1 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.LinkedHashMap$Entry from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.security.action.GetPropertyAction from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.jkernel.DownloadManager from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.jkernel.DownloadManager$1 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.jkernel.DownloadManager$2 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ClassLoader$3 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.ExpiringCache$Entry from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ClassLoader$NativeLibrary from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.StringCoding$StringEncoder from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.nio.charset.CharsetEncoder from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.nio.cs.ext.GB18030$Encoder from C:\Program Files\Java\jre6\lib\charsets.jar]
[Loaded sun.nio.cs.Surrogate$Parser from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.nio.cs.Surrogate from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.Closeable from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.InputStream from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.FileInputStream from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.FileDescriptor from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.Flushable from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.OutputStream from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.FileOutputStream from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.FilterInputStream from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.BufferedInputStream from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.concurrent.atomic.AtomicReferenceFieldUpdater from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.reflect.misc.ReflectUtil from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.FilterOutputStream from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.PrintStream from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.BufferedOutputStream from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.Writer from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.OutputStreamWriter from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.nio.cs.StreamEncoder from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.BufferedWriter from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Terminator from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.SignalHandler from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Terminator$1 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.Signal from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.NativeSignalHandler from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.OSEnvironment from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.io.Win32ErrorMode from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Compiler from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Compiler$1 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.Launcher from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.net.URLStreamHandlerFactory from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.Launcher$Factory from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.SecureClassLoader from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.net.URLClassLoader from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.Launcher$ExtClassLoader from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.security.util.Debug from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Package from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.net.URL from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.CodeSource from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Void from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.cert.Certificate from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.ClassFormatError from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.IllegalArgumentException from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.IOException from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.URLClassPath from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.AssertionStatusDirectives from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.JavaNetAccess from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.net.URLClassLoader$7 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.PermissionCollection from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.StringTokenizer from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.PrivilegedExceptionAction from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.Launcher$ExtClassLoader$1 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.MetaIndex from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.Reader from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.BufferedReader from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.InputStreamReader from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.FileReader from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.nio.cs.StreamDecoder from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.ArrayList from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.reflect.Array from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.Locale from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.concurrent.ConcurrentMap from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.concurrent.ConcurrentHashMap from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.concurrent.locks.Lock from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.concurrent.locks.ReentrantLock from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.concurrent.ConcurrentHashMap$Segment from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.concurrent.locks.AbstractOwnableSynchronizer from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.concurrent.locks.AbstractQueuedSynchronizer from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.concurrent.locks.ReentrantLock$Sync from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.concurrent.locks.ReentrantLock$NonfairSync from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.concurrent.locks.AbstractQueuedSynchronizer$Node from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.concurrent.ConcurrentHashMap$HashEntry from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.CharacterDataLatin1 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.ObjectStreamClass from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.net.www.ParseUtil from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.BitSet from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.net.Parts from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.net.URLStreamHandler from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.net.www.protocol.file.Handler from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.util.HashSet from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.net.www.protocol.jar.Handler from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.Launcher$AppClassLoader from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.Launcher$AppClassLoader$1 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.SystemClassLoaderAction from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.VMSupport from C:\Program Files\Java\jre6\lib\rt.jar]
[Opened C:\Program Files\Java\jre6\lib\ext\dnsns.jar]
[Opened C:\Program Files\Java\jre6\lib\ext\localedata.jar]
[Opened C:\Program Files\Java\jre6\lib\ext\sunjce_provider.jar]
[Opened C:\Program Files\Java\jre6\lib\ext\sunmscapi.jar]
[Opened C:\Program Files\Java\jre6\lib\ext\sunpkcs11.jar]
[Loaded java.net.URLClassLoader$1 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.net.util.URLUtil from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.URLClassPath$3 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.URLClassPath$Loader from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.URLClassPath$JarLoader from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.PrivilegedActionException from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.URLClassPath$FileLoader from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.Resource from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.URLClassPath$FileLoader$1 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.nio.ByteBuffered from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.Permissions from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.net.URLConnection from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.net.www.URLConnection from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.net.www.protocol.file.FileURLConnection from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.net.ContentHandler from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.net.UnknownContentHandler from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.net.www.MessageHeader from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.FilePermission from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.FilePermission$1 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.Policy from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.security.provider.PolicyFile from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.Policy$UnsupportedEmptyCollection from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.FilePermissionCollection from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.AllPermission from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.UnresolvedPermission from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.BasicPermissionCollection from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded sun.misc.JavaSecurityProtectionDomainAccess from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.ProtectionDomain$2 from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.ProtectionDomain$Key from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.security.Principal from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded Test from file:/D:/dev/Test/bin/]
sun.misc.Launcher$AppClassLoader@1a16869
[Loaded java.lang.Shutdown from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Shutdown$Lock from C:\Program Files\Java\jre6\lib\rt.jar]
[/code]
从上面的加载顺序可以看出,一个ClassLoader的加载路径基本先找JRE的lib目录下面的resource.jar和rt.jar文件(resource.jar里面是很多properties文件用来定义配置项),然后进行load,在最后定位到Test类通过AppClassLoader进行加载。
以上大概描述了下JVM当中的内存处理的理解,下面继续Tomcat的启动。
在JVM启动之后,载入Tomcat相关Class时,首先Setup需要用到的ClassLoaders,分别对应不同路径下的jar包。
在Create Classloader时,tomcat通过批量读取指定路径下的jar包,统一创建一个classloader,最终通过org.apache.catalina.startup.ClassLoaderFactory.createClassLoader方法处理。
在org.apache.catalina.startup.Bootstrap.createClassLoader方法中通过MBeanServer的注册统一管理当前的ClassLoader,代码:
[code]
// Retrieving MBean server
MBeanServer mBeanServer = null;
if (MBeanServerFactory.findMBeanServer(null).size() > 0) {
mBeanServer = MBeanServerFactory.findMBeanServer(null).get(0);
} else {
mBeanServer = ManagementFactory.getPlatformMBeanServer();
}

// Register the server classloader
ObjectName objectName =
new ObjectName("Catalina:type=ServerClassLoader,name=" + name);
mBeanServer.registerMBean(classLoader, objectName);
[/code]
通过MBeanFactory取得一个MBeanServer实例,并将init之后的ClassLoader注册,之后负责针对该MBean管理。
[code]
Thread.currentThread().setContextClassLoader(catalinaLoader);
SecurityClassLoad.securityClassLoad(catalinaLoader);
[/code]
接下来设置当前线程的ContextClassLoader为CatalinaLoader,在Thread类当中存在一个contextClassLoader(类型为ClassLoader)的属性,用来在当前线程需要创建新的Class的时候进行加载。加载规则是首先使用父ClassLoader进行载入,如果无法载入,再自己进行Class载入。
然后通过反射方式取得一个Catalina类的实例,并调用它的setParentClassLoader方法将它的ParentClassLoader,在Catalina类当中存在一个parentClassLoader的属性,在类初始化时默认被设置为:
[code]
/**
* The shared extensions class loader for this server.
*/
protected ClassLoader parentClassLoader = Catalina.class.getClassLoader();
[/code]
通过System.out.println(new Catalina().getClass().getClassLoader().toString());得到结果:sun.misc.Launcher$AppClassLoader@18d107f,可见默认的Catalina的ClassLoader是AppClassLoader。那么为什么在这里设置成为sharedLoader(在set这个sharedLoader时候,由于properties当中相应配置为空,则默认被设置成为commonLoader)呢?这个在之后Catalina类在load的时候是要用到的。
在init()方法的最后一步,将反射生成的catalina实例赋值给了bootstrap当中的catalinaDaemon变量。做为之后load、start、stop server的时候被调用的实例。
在接下来通过启动参数进行判定,进入不同的分支:
参数为startd:
[code]
args[args.length - 1] = "start";
daemon.load(args);
daemon.start();
[/code]
将参数重置为start主要为了调用load方法操作。(注:这个是apache先前的Bug 47881,先前写的是args[0])。
参数为start:
[code]
daemon.setAwait(true);
daemon.load(args);
daemon.start();
[/code]
这个比startd增加了一个setAwait操作,其实质是在Server启动完成之后,主线程并不退出,而是执行server.setAwait()方法,在该方法中启动一个Socket监听8005端口(timeout为十秒钟),用于监听来自8005端口上的远程关闭命令。
然后是stop和stopd参数,如果以start方式启动tomcat时,在setAwait当中一直while(true),知道发现shutDown的命令为止,则跳出循环,执行stop()方法。
当执行stop方法是,首先查找server,如果不存在,则通过Digest方式进行关闭;查到server则进行socket方式传输shutdown命令进行远程关闭。使用stopd参数则直接调用:
[code]
// Shut down the server
try {
getServer().stop();
} catch (LifecycleException e) {
log.error("Catalina.stop", e);
}
[/code]
所以对应于tomcat的启动方式start和startd,在关闭时应该分别调用stop和stopd,在使用eclipse将tomcat嵌入进去的时候,应该通过startd和stopd方式进行启动和终止,需要tomcat独立运行的时候则通过start和stop进行启动和终止,通过主线程维持连接。

在启动之前的load方式:
在start之前,load当中通过digest的方式进行系统组件的加载。通过反射调用Catalina的load方法,在其中通过createStartDigester();方法创建digester对象,读取系统的server.xml文件将其中的各个组件加入add到digester当中。


本地的启动描述文件的路径:
D:/dev/tomcat7.0/output/build/webapps/docs/architecture/startup/serverStartup.txt
文本:
http://tomcat.apache.org/tomcat-7.0-doc/architecture/startup/serverStartup.txt
UML:
http://tomcat.apache.org/tomcat-7.0-doc/architecture/startup/serverStartup.pdf
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值