之前一直以为程序启动的时候,会由Bootstrap ClassLoader加载rt.jar包下的所有类(Integer String等)。但在研究jdbc源码的时候,实验了一次 java.sql.DriverManager
类的加载时机:
- 如果在测试类中没有使用DriverManager,发现DriverManager类并没有被加载;
- 如果测试类中使用了DriverManager,发现DriverManager类被加载了。
我想问的是,程序启动的时候,Bootstrap ClassLoader并不是加载rt.jar包下所有的类?如果不是,那他加载的是哪些?
Java程序启动时,并不是一次把所有的类全部加载后再运行,它总是先把保证程序运行的基础类一次性加载到jvm中,其它类等到jvm用到的时候再加载。
va中的类大致分为三种: 1.系统类 2.扩展类 3.由程序员自定义的类
java类加载器又分:
1)Bootstrap ClassLoader
负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类
2)Extension ClassLoader
负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包
3)App ClassLoader
负责记载classpath中指定的jar包及目录中class
4)Custom ClassLoader
属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader
加载过程中会先检查类是否被已加载,检查顺序是自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个classloader已加载就视为已加载此类,保证此类只所有ClassLoader加载一次。而加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。
由此可见,会首先把保证程序运行的基础类一次性加载到jvm中。而根据资料java最早就是为嵌入式系统而设计的,内存宝贵。所有如果开始就把所有,用的到、用不到的类都加载到jvm中,势必会占用很多宝贵的内存,而且有些class可能压根在整个运行过程中都不会使用。