快捷搜索:

静态库、动态连接库

静态库、动态连接库

法度榜样体例一样平常需经编辑、编译、连接、加载和运行几个步骤。在我们的利用中,有一些公共代码是必要反复应用,就把这些代码编译为“库”文件;在连接步骤中,连接器将从库文件取得所需的代码,复制到天生的可履行文件中。这种库称为静态库,其特征是可履行文件中包孕了库代码的一份完备拷贝;毛病便是被多次应用就会有多份冗余拷贝。

为了降服这个毛病可以采纳动态连接库。这个时刻连接器仅仅是在可履行文件中打上标志,阐明必要应用哪些动态连接库;当运行法度榜样时,加载器根据这些标志把所需的动态连接库加载到内存。

别的在当前的编程情况中,一样平常都供给措施让法度榜样在运行的时刻把某个特定的动态连接库加载并运行,也可以将其卸载(例如Win32的LoadLibrary()&FreeLibrary()和Posix的dlopen()&dlclose())。这个功能被广泛地用于在法度榜样运行时候更新某些功能模块或者是法度榜样外不雅。

What is ClassLoader?

与通俗法度榜样不合的是,Java法度榜样(class文件)并不是本地的可履行法度榜样。当运行Java法度榜样时,首先运行JVM(Java虚拟机),然后再把Java class加载到JVM里头运行,认真加载Java class的这部分就叫做Class Loader。

JVM本身包孕了一个ClassLoader称为Bootstrap ClassLoader,和JVM一样,Bootstrap ClassLoader是用本地代码实现的,它认真加载核心Java Class(即所有java.*开首的类)。别的JVM还会供给两个ClassLoader,它们都是用Java说话编写的,由Bootstrap ClassLoader加载;此中Extension ClassLoader认真加载扩展的Java class(例如所有javax.*开首的类和寄放在JRE的ext目录下的类),Application ClassLoader认真加载利用法度榜样自身的类。

When to load the class?

什么时刻JVM会应用ClassLoader加载一个类呢?当你应用java去履行一个类,JVM应用Application ClassLoader加载这个类;然后假如类A引用了类B,不管是直接引用照样用Class.forName()引用,JVM就会找到加载类A的ClassLoader,并用这个ClassLoader来加载类B。

Why use your own ClassLoader?

彷佛JVM自身的ClassLoader已经足够了,为什么我们还必要创建自己的ClassLoader呢?

由于JVM自带的ClassLoader只是相识从本地文件系统加载标准的java class文件,假如编写你自己的ClassLoader,你可以做到:

1)在履行非置信代码之前,自动验证数字署名

2)动态地创建相符用户特定必要的定制化构建类

3)从特定的场所取得java class,例如数据库中

4) 等等

事实上当应用Applet的时刻,就用到了特定的ClassLoader,由于这时必要从收集上加载java class,并且要反省相关的安然信息。

今朝的利用办事器大年夜都应用了ClassLoader技巧,纵然你不必要创建自己的ClassLoader,懂得其道理也有助于更好地支配自己的利用。

ClassLoader Tree & Delegation Model

当你抉择创建你自己的ClassLoader时,必要承袭java.lang.ClassLoader或者它的子类。在实例化每个ClassLoader工具时,必要指定一个父工具;假如没有指定的话,系统自动指定ClassLoader.getSystemClassLoader()为父工具。如下图:

在Java 1.2后,java class的加载采纳所谓的委托模式(Delegation Modle),当调用一个ClassLoader.loadClass()加载一个类的时刻,将遵照以下的步骤:

1)反省这个类是否已经被加载进来了?

2)假如还没有加载,调用父工具加载该类

3)假如父工具无法加载,调用本工具的findClass()取得这个类。

以是当创建自己的Class Loader时,只必要重载findClass()这个措施。

Unloading? Reloading?

当一个java class被加载到JVM之后,它有没有可能被卸载呢?我们知道Win32有FreeLibrary()函数,Posix有dlclose()函数可以被调用来卸载指定的动态连接库,然则Java并没有供给一个UnloadClass()的措施来卸载指定的类。

在Java中,java class的卸载仅仅是一种对系统的优化,有助于削减利用对内存的占用。既然是一种优化措施,那么就完全是JVM自行抉择若何实现,对Java开拓职员来说是完全透明的。

在什么时刻一个java class/interface会被卸载呢?Sun公司的原话是这么说的:"class or interface may be unloaded if and only if its class loader is unreachable. Classes loaded by the bootstrap loader may not be unloaded."

事实上我们关心的不是若何卸载类的,我们关心的是若何更新已经被加载了的类从而更新利用的功能。JSP则是一个异常范例的例子,假如一个JSP文件被变动了,利用办事器则必要把变动后的JSP从新编译,然后加载新天生的类来相应后继的哀求。

着实一个已经加载的类是无法被更新的,假如你试图用同一个ClassLoader再次加载同一个类,就会获得非常(java.lang.LinkageError: duplicate class definition),我们只能够从新创建一个新的ClassLoader实例来再次加载新类。至于原本已经加载的类,开拓职员不必去管它,由于它可能还有实例正在被应用,只要相关的实例都被内存收受接收了,那么JVM就会在适当的时刻把不会再应用的类卸载。

您可能还会对下面的文章感兴趣: