`

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(),方法内容如下:
    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);
        }
    }

以上代码将分别加载Tomcat的三种包:common,server,shared。分别对应catalina.properties文件中:
common.loader=${catalina.home}/lib,${catalina.home}/lib/*.jar

server.loader=

shared.loader=

即为以上路径下面对应的jar包设置ClassLoaders。

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

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



三个模块:
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

之后,读取代码当中的静态初始化内容:
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;
......

对于第一行代码创建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当中压栈和出栈都是以帧为单位的(栈是跟着线程走的,有线程就有栈),每一帧包含的信息包括:



在这个图当中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()测试得到:
[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]

从上面的加载顺序可以看出,一个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,代码:
        // 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);

通过MBeanFactory取得一个MBeanServer实例,并将init之后的ClassLoader注册,之后负责针对该MBean管理。
Thread.currentThread().setContextClassLoader(catalinaLoader);
SecurityClassLoad.securityClassLoad(catalinaLoader);

接下来设置当前线程的ContextClassLoader为CatalinaLoader,在Thread类当中存在一个contextClassLoader(类型为ClassLoader)的属性,用来在当前线程需要创建新的Class的时候进行加载。加载规则是首先使用父ClassLoader进行载入,如果无法载入,再自己进行Class载入。
然后通过反射方式取得一个Catalina类的实例,并调用它的setParentClassLoader方法将它的ParentClassLoader,在Catalina类当中存在一个parentClassLoader的属性,在类初始化时默认被设置为:
    /**
     * The shared extensions class loader for this server.
     */
    protected ClassLoader parentClassLoader =  Catalina.class.getClassLoader();

通过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:
                
args[args.length - 1] = "start";
daemon.load(args);
daemon.start();

将参数重置为start主要为了调用load方法操作。(注:这个是apache先前的Bug 47881,先前写的是args[0])。
参数为start:
                
daemon.setAwait(true);
daemon.load(args);
daemon.start();

这个比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参数则直接调用:
       
        // Shut down the server
        try {
            getServer().stop();
        } catch (LifecycleException e) {
            log.error("Catalina.stop", e);
        }

所以对应于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
  • 大小: 35.7 KB
  • 大小: 34.9 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics