动态加载vs静态加载

本文详细阐述了静态库与动态库的特点及应用场景,包括各自的加载方式、灵活性、更新便利性等,有助于理解不同类型的库文件如何影响软件开发。

转自:http://blog.youkuaiyun.com/zhangchao3322218/article/details/8084521

动态加载:

1:灵活,可以在需要的时候用LoadLibrary进行加载,在不需要的时候用FreeLibrary进行卸载,这样可以不必占用内存。
2:可以在没有dll时候发现,而不致程序报错。
3:加载程序中有条件才运行的库。
4:热更新,在不停止程序的前提下进行更新。
5:复杂一些,需要显示获得函数地址。
6:dll没有对应的lib文件,此时只能进行动态加载。

静态加载:
1:简单方便
2:没有dll时,系统报错
3:加载运行很久的库
4:dll必需有相应的lib文件

加载方法:
1、确保有a.dll和a.lib,两个文件都有的话可以用静态加载的方式。
2、在.cpp文件中通过#pragma comment(lib, "a.lib") 加载lib,并包含相应的头文件,就可以使用dll中的函数了~


      所谓"程序库",简单说,就是包含了数据和执行码的文件。其不能单独执行,可以作为其它执行程序的一部分,来完成执行功能。库的存在,可以使得程序模块化,可以加快程序的再编译,可以实现代码重用,可以使得程序便于升级。 
      程序库可分三类:静态库,共享库和动态加载库。 
      静态库,是在执行程序运行前就已经加入到执行码中,在物理上成为执行程序的一部分;共享库,是在执行程序启动时加载到执行程序中,可以被多个执行程序共享使用。动态加载库,其实并不是一种真正的库类型,应该是一种库的使用技术,应用程序可以在运行过程中随时加载和使用库。 
     建议库开发人员创建共享库,比较明显的优势在于库是独立的,便于维护和更新;而静态库的更新比较麻烦,一般不做推荐。然而,它们又各有优点,后面会讲到。在C++编程中,要使用动态加载技术,需要参考文章"C++ dlopen MINI-Howto"。 

      静态库可以认为是一些目标代码的集合。按照习惯,一般以".a"做为文件后缀名。使用ar(archiver)命令可以创建静态库。因为共享库有着更大的优势,静态库已经不被经常使用。但静态库使用简单,仍有使用的余地,并会一直存在。 
     静态库在应用程序生成时,可以不必再编译,节省再编译时间。但在编译器越来越快的今天,这一点似乎已不重要。如果其他开发人员要使用你的代码,而你又不想给其源码,提供静态库是一种选择。从理论上讲,应用程序使用了静态库,要比使用动态加载库速度快1-5%,但由于莫名的原因,实际上可能并非如此。由此看来,除了使用方便外,静态库可能并非一种好的选择。 
### 概念 - **动态加载**:在程序运行时,根据实际需求决定是否加载某个类,而非在编译阶段就确定所有要使用的类,增加了程序的灵活性 [^1]。 - **静态加载**:在编译前就需要提供所有功能的定义,若缺少则无法编译通过,即所有类在编译时就确定要加载 [^1]。 ### 原理 - **动态加载**:通常借助`ClassLoader`类实现,默认的`ClassLoader`根据类的完整路径名加载类。Java默认提供了三种类加载器,分别是启动类加载器`BootstrapClassLoader`(根加载器)、扩展类加载器`ExtClassLoader`和应用类加载器`AppClassLoader`。可以使用`Class.forName()`方法动态加载类,该方法会调用类加载器将指定类加载到JVM中,并返回对应的`Class`对象。示例代码如下: ```java try { // 动态加载类 Class<?> myClass = Class.forName("com.example.MyClass"); } catch (ClassNotFoundException e) { e.printStackTrace(); } ``` - **静态加载**:在编译时,编译器会检查所有引用的类是否存在,若存在则将其编译进字节码文件。在程序启动时,JVM会根据字节码文件的信息,使用类加载器将所有需要的类加载到内存中。例如,在代码中直接使用`new`关键字创建对象时,对应的类会在编译时就被确定要加载,在程序运行时会被静态加载。示例代码如下: ```java // 静态加载类 MyClass obj = new MyClass(); ``` ### 区别 - **加载时机**:静态加载在编译时确定,程序启动时加载动态加载程序运行时根据条件决定是否加载 [^1]。 - **灵活性**:动态加载可以根据运行时的不同情况选择加载不同的类,使程序更灵活;静态加载缺乏这种灵活性,一旦编译完成,加载的类就固定了 [^1]。 - **编译依赖性**:静态加载要求编译时所有依赖的类都必须存在,否则无法编译通过;动态加载可以在运行时处理类不存在的情况,不会影响编译。 - **性能开销**:静态加载程序启动时一次性加载所有类,可能会增加启动时间和内存开销;动态加载按需加载类,减少了不必要的类加载,可能会提高程序的性能和内存使用效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值