JVM类加载机制

来源:互联网 发布:windows.h x86 x64 编辑:程序博客网 时间:2024/05/21 10:54

      在用JDBC的时候遇到的一个用法:

Class.forName("org.firebirdsql.jdbc.FBDriver");
Connection conn = DriverManager.getConnection(...);

      第一句其实就是加载类FBDriver,并且实例初始化了一个类的对象,在这个FBDriver中很可能把自己注册给了DriverManager这个类,所以后面可以调用这个JDBC的驱动。

      并不是加载到一个类就会实例化并初始化的,“If name(org.firebirdsql.jdbc.FBDriver) denotes an array class, the component type of the array class is loaded but not initialized.”

      “jvm在初期是将.java文件,编译成.class文件,当程序运行的时候,Java 虚拟机就将编译生成的 .class 文件按照需求和一定的规则加载进内存,组织成为一个完整的Java应用程序,jvm会把每个单独的类和接口编译成一个单独的.class文件,这些文件对于 Java运行环境来说就是一个个可以动态加载的单元。我们可以在不重新编译其它代码的情况下,只编译需要修改的单元,并把修改文件编译后的 .class 文件放到 Java的路径当中,等到下次该 Java 虚拟机器重新激活时,这个逻辑上的 Java 应用程序就会因为加载了新修改的 .class 文件,自己的功能也做了更新,这就是 Java 的动态性。 


      对比C++程序dll动态库的要灵活的太多,如果导出的为类并且类中有虚函数,那么只要类中接口方法稍有变化甚至顺序变化,所有用到此dll的文件都要重新编译!因为有虚函数类就有一个虚表,而这个虚表中记录的是offset,而offset又是根据虚函数声明的位置隐式确定的。所以在增加虚函数会造成vtable的变化,而已有的二进制文件中没有更新。而且如果有继承关系,那么这个关系就更容易错误了。

      对比java,java中实际是把c++中的linking这一步骤放在了jvm的类加载中实现,是动态的实现这可能是与c++最大的区别,在运行java程序时候才进行的,这样链接错误就会较少。java的类,在内存中也是一个对象,也需要初始化等操作。

参考:
http://blog.csdn.net/java2000_wl/article/details/8222876
http://blog.csdn.net/java2000_wl/article/details/8040633
http://liuqimeng1.iteye.com/blog/679078
http://lavasoft.blog.51cto.com/62575/184547
0 0