动态装载
此条目可参照英语维基百科相应条目来扩充。 (2018年5月27日) |
动态装载,别称动态加载(英语:Dynamic Loading)是一种程序运行机制,能让电脑程序在运行时(而不是编译时)装载库(或者其他二进制对象)到内存中,然后检索库中函数和变量的地址,并执行这些函数或访问这些变量,且能在不需要时将库从内存中卸载。动态装载、静态链接(static linking)与动态链接(dynamic linking)(注意区分动态装载与动态链接的微妙差别)是复用其他软件代码的三种机制,不同于静态链接和动态链接,这种机制允许电脑程序在没有某些库的情况下启动,然后在运行的过程中发现可用的库从而获得额外的功能。
历史沿革
动态装载早在1960年代的IBM/360操作系统中就已经广泛使用,尤其是在输入/输出子模块,以及COBOL和PL/I的运行时库中。装载的过程对于应用程式开发者是透明的,主要由操作系统或者输入输出子系统自动处理。这样做的好处有:
- 修复子系统漏洞时只需要打一次补丁即可,而不需要重新链接
- 程序库可以免于被胡乱修改而造成严重影响
IBM于1970年代开发的战略性事务处理操作系统CICS中,不仅在普通应用程式级别上使用了动态加载,甚至在内核级别都广泛采取这种机制,这使得用户可以在不用重启CICS操作系统的前提下,就可以对应用程式做任何级别的漏洞修复。
应用
动态装载经常用于插件。[1][Apache http伺服器的例子待补充翻译]
热部署
热部署(英:Hot deployment)是,伺服器不需要重启的情况下,修改软件或者软件。[2]
编程语言
C/C++
并非所有操作系统都支持动态装载。类UNIX操作系统通过C编程语言实现而成的dl库提供该类功能。在微软的视窗操作系统采用Windows应用程式接口。
类UNIX系统[3][4] | 视窗系统 | |
---|---|---|
申明 | dlfcn.h | windows.h |
定义 | libdl | kernel32.dll |
装载库 | dlopen | LoadLibrary LoadLibraryEx |
解析库 | dlsym | GetProcAddress |
卸载库 | dlclose | FreeLibrary |
Java
对于Java语言而言,类的动态装载是通过类加载器(ClassLoader
)该对象进行实现的。示例如下:
Class type = ClassLoader.getSystemClassLoader().loadClass(name);
Object obj = type.newInstance();
通过反射机制的方式,我们可以加载仍旧未被加载类。并通过下面例子,进行操作加载成功的类。
Class type = Class.forName(name);
Object obj = type.newInstance();
当我们想要卸载一个类,很遗憾,至今没有一种简单的并且程序可控制的的方法(不存在原生方法)。打个比方,当开发者有这样的需求时——正在使用的类加载器(ClassLoader
)不是系统类加载器,同时该加载器又无法被卸载,而你又想要卸载掉类。 此时,开发者就不得不了解机制细节,否则就无法确认类是否真的被卸载。这样的操作十分麻烦。
参考资料
- ^ Autoconf, Automake, and Libtool: Dynamic Loading. [2019-12-19]. (原始内容存档于2020-02-24).
- ^ Hot deployment and dynamic reloading. (原始内容存档于2019-12-19).
- ^ dlfcn.h. The IEEE and The Open Group. [2013-12-15]. (原始内容存档于2019-10-08) (英语).
- ^ David A. Wheeler. Program Library HOWTO. The Linux Documentation Project. 2003-04-11 [2013-12-15]. (原始内容存档于2020-11-12) (英语).