标签:
【静态链接和动态链接】
静态链接:源程序编译之后,如果想要执行,先对目标文件进行链接,链接完成后如果执行了,就把链接好的都装载进内存
缺点:
<1>如果一个目标文件被重复使用,每次都会把目标文件载入内存,造成浪费;
<2>如果相对某个目标文件进行更新,需要先把这个目标文件重新编译+链接,然后重新载入内存。
动态链接:在程序开始运行后(装载到内存)才开始把目标文件依次加载到内存然后编译成可执行文件
优点:
<1>可以避免同一个目标文件的多次链接到内存;
<2>更新某个目标文件直接拿新的目标文件直接覆盖,不要再编译。
[插件]:
在程序运行时动态的链接,实现程序功能的扩展。
比如开发了一款浏览器,浏览器对外提供了程序的接口(封装好的编译好的目标文件(二进制)),第三方的公司下载了我们的接口后导入到某个IDE的新建项目后开始开发,根据我们提供的API文档它们开发出了一款换肤的插件(通过实现类库中的方法),IDE提供给源程序一些语法检查,但依然需要编译,编译成功了我们上传到服务器。用户下载到本地之后,需要重启浏览器(运行),然后下载的插件被检测到,开始和浏览器类库链接,而浏览器类库又与系统类库进行链接,这样这个新的插件就可以被装载到虚拟内存中了,初始化完毕后,就能看到刚才的插件开始运行了。
[软件的出现]
操作系统对外提供了一些基本的运行库,比如输入输出等,这些类库是已编译但未链接的二进制文件.o/.obj;
用户使用IDE开发软件时,集成环境提供了对应的类库,比如C标准类库,这种类库是对基本运行库的部分的包装;
类库中提供类和方法的接口,我们通过实现接口来进行功能的实现,但是不同编译器编译得到的类库大多是无法兼容的;
可对于别人写好编译好的jar类库我们可以导入到项目中,这是因为java先根据类库编译成了中间码,类库与平台无关;
在开发的过程中,运行库会提供给我们一套API文档,文档中标识类的作用以及实现的方法等;
如果我们直接在本类中调用相关的方法会出错,因为编译的时候,访问权限使得本类无法直接访问该类库;
所以如果想要使用集成环境提供/自定义的类库,就得导入include或引入import,这样才能进行访问;
当我们开发好了软件,开始编译:编译系统会把当前源代码编译成二进制的段文件,此时和外部类还未建立连接;
两种链接方案:
<1> [静态链接]:本类的方法会调用导入的类库中相应类的方法(API),这些方法先进行部分的自己的操作;
接着的操作中会调用系统提供的API以及一些辅助库,来实现基本的系统操作,这些系统库/辅助库/C标准库的所有库本质上都是ELF/PE段文件,链接的时候分类/分页都加载到应用程序的虚拟内存中去。
[执行]虚拟内存建立和物理内存的映射,cpu开始执行。
<2>[执行]
[动态链接]:编译好的源文件和系统库/辅助库/c标准库在运行之后才开始链接,即开始运行后,什么时候需要某个库我们再把该库链接到虚拟内存中,并且在链接某库到虚拟内存中时检查虚拟内存中是否存在该库,如果存在就不用再链接直接使用已存在的库。
[真正执行]:虚拟内存建立和物理内存的映射,cpu开始执行。
[注]:虚拟内存并未映射到真实的物理内存中,它只是应用程序中的段对应的从0开始的内存地址,当开始运行的时候,才会通过虚拟内存分页的方法建立起虚拟内存到物理内存的映射,那时才算是程序真正在运行。
[注]:编译完成后库文件依然存在,而链接的过程就是编译后的文件调用库文件再调用系统api的过程。静态链接必须先链接(初始化)才能成为可执行文件,动态链 接在执行时开始先链接(初始化)接着执行,不可避免动态链接损失了一定时间,但增加了减少了空间和灵活性。
标签:
原文地址:http://www.cnblogs.com/yzxk/p/4457949.html