Java Performance 总结(1. Class Loader)

关于Java性能方面的东西,涉及挺多。一直想写个总结。

第一部分,还是介绍class loader(类加载器,译文不如原文流畅了,估计用英文原词吧),它主要用于在Java虚拟机运行时加载所需要的类。

 

一、这些类,有两部分:一部分是你的应用程序中的java类,另一部分是Java API中的类文件。加载器有两个重要的工作:

 

1. loading: 找到一个类, 并导入它的二进制数据表示

2. linking: 执行验证,准备,以及可能的解析工作

       验证:确保导入的类型是正确的

       准备:为类变量准备足够内存,并为相应的变量执行初始化操作

       解析:从符号引用变为直接引用,同时加载该类所引用的所有类

 

二、JVM中缺省的class loader:

1. $JAVA_HOME/jre/lib/rt.jar被Bootstrap Class loader加载:

    注意看到:sun/misc/Launcher$ExtClass, sun/misc/Launcher$AppClass这两个class

    它是所有Class Loader的root class loader

2. Extention class loader:

    来源于$JAVA_HOME/jre/lib/ext/*.jar

3. System Class Loader,这一级,就到了用户定义的$CLASSPATH中的class的加载了

    用户定义的classloader都是System class loader的子class loader.

 

三、类加载顺序:

1. 首先从已经加载的cache中查找,如果加载过,则返回

2. 从父classloader中加载(递归查找), 这确保API中的class都是被BootStrap class loader加载

3. 如果2中找不到,则使用当前的classloader进行加载

这也可以看出,一个class loader只能看到它的祖先class loader和它自身加载的类。看不到子class loader加载的类。

    System Class Loader可以通过 cl.getSystemClassLoader()得到。

 

四、指定系统classloader的参数:

Boot Class Path (Bootstrap CL)
-Xbootclasspath:<dir|zip|jar separated by ;or:>
-Xbootclasspath:/a  (append to the end)
-Xbootclasspath:/p  (prepend to the front)

Extention Class Path (Extention CL)
-Djava.ext.dirs= <dir|zip|jar separated by ;or:>
System Class Path (System CL)
-cp or -classpath <dir|zip|jar separated by ;or:>
-Djava.class.path= <dir|zip|jar separated by ;or:>

 

五、显式加载和隐式加载

1. 显式方式:

    cl.loadClass()  (cl是java.lang.ClassLoader的一个实例)

    Class.forName() (当前classloader是起始classloader)

 

2. 隐式方式:

    当被当成引用,类进行实例化,以及产生继承关系时,JVM将进行必要的解析并加载该类

 

    因此,classloader显式的加载一个类,并隐式的加载所有其引用类

 

六、ClassLoader的跟踪信息:

java -verbose:class  (class loading)
java -verbose:gc (gc output)
java -verbose:jni (jni output)

 

七、ClassLoader中的path

URLClassLoader l = new URLClassLoader(new URL[] { new URL(     "file://D:/eclipse3.1/workspace/testclass/")});
URLClassLoader l = new URLClassLoader(new URL[] { new URL(     "file://D:/eclipse3.1/workspace/testclass")});
以'/'结束,表示目录路径,可加载下边所有的class; 如果不是以'/'结束,则意味着它是一个jar或zip文件。

 

子类的父类的classloader必须是子类的classloader或祖先classloader。不同的classloader加载的同名class不能相互cast。

 

获取JVM当前线程栈信息:

Windows:
Ctrl + Break

Unix/Linux:
Ctrl + /
kill –QUIT <pid>
kill –SIGQUIT <pid>

 


参考资料:

Inside the Java Virtual Machine
Demystifying class loading problems
http://www-128.ibm.com/developerworks/java/library/j-dclp1/index.html
Java Platform Performance: Strategies and Tactics
http://java.sun.com/docs/books/performance/1st_edition/html/JPTitle.fm.html
http://www.javaperformancetuning.com/tips/nio.shtml


 

  

 

posted @ 2010-06-30 06:50  张长胜  阅读(201)  评论(0编辑  收藏  举报