动态链接库(Dynamic Link Library 或者 Dynamic-link Library,缩写为 DLL),是微软公司在微软Windows操作系统中,实现共享函数库概念的一种方式。这些库函数的扩展名是 ”.dll"、".ocx"(包含ActiveX控制的库)或者 “.drv”(旧式的系统驱动程序)。
总结重点:
1、提供了一种方法可以调用不属于可执行代码的函数
2、函数的可执行代码位于一个DLL文件中,该DLL文件包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数,dll 并不是所有数据都能被访问到,必须要进行导出。
3、更容易地更新应用于各个模块,而不会影响该程序的其他部分,
4、动态链接库文件,是一种不可执行的二进制程序文件,它允许程序共享执行特殊任务必须的代码和其他资源,如果使用隐式链接的方式使用动态链接库,必须要 dll 文件。
5、Windows 提供的DLL文件中包含了允许基于 Windows 的程序在 Windows 环境下操作的许多函数和资源。一般被存放在电脑的"C:\Windows\System32" 目录下。Windows 中,DLL 多数情况下是带有 “.dll” 扩展名的文件,但也可能是 ".ocx"或其他扩展名;Linux系统中常常是 “.so” 的文件。它们向运行于 Windows操作系统下的程序提供代码、数据或函数。程序可根据 DLL 文件中的指令打开、启用、查询、禁用和关闭驱动程序
6、动态链接库在内存中始终只保存了一份数据,节约应用程序所需要的磁盘和内存空间;
7、生成动态链接库的时候会附带一个 lib,这个lib叫做导入库,导入库同于提供导出函数和数据在 dll 中所处的位置,不提供代码。
machine language是一种指令集体系,而包含在其中的指令集是machine code(native code)。计算机设计者通过硬件赋予计算机操作功能,在不同型号的计算机上支持的指令集不同,machine language不相通。
Native code is computer programming (code) that is compiled to run with a particular processor (such as an Intel x86-class processor) and its set of instructions. If the same program is run on a computer with a different processor, software can be provided so that the computer emulates the original processor. In this case, the original program runs in “emulation mode” on the new processor and almost certainly more slowly than in native mode on the original processor. (The program can be rewritten and recompiled so that it runs on the new processor in native mode.)
本机代码是计算机编程(代码),编译为与特定处理器(例如 Intel x86 级处理器)及其指令集一起运行。如果在具有不同处理器的计算机上运行相同的程序,则可以提供软件以使计算机模拟原始处理器。在这种情况下,原始程序在新处理器上以“仿真模式”运行,并且几乎肯定比原始处理器上的本机模式慢。 (该程序可以重写并重新编译,以便它以纯模式在新处理器上运行。)
Native code can also be distinguished from bytecode (sometimes called interpreted code), a form of code that can be said to run in a virtual machine (for example, the Java Virtual Machine). The virtual machine is a program that converts the platform-generalized bytecode into the native code that will run in a specific processor. Microsoft’s .NET compilers for its Visual Basic, C#, and JavaScript languages produce bytecode (which Microsoft calls Intermediate Language). Java bytecode and Microsoft’s Intermediate Language can be compiled into native code before execution by a just-in-time compiler for faster performance.
本机代码也可以与字节码(有时称为解释代码)区分开来,字节码是一种可以说在虚拟机中运行的代码形式(例如,Java 虚拟机)。虚拟机是一个程序,它将平台通用字节码转换为将在特定处理器中运行的本机代码。微软用于 Visual Basic,C #和 JavaScript 语言的.NET 编译器产生字节码(微软称之为中间语言)。Java 字节码和 Microsoft 的中间语言可以在由即时编译器执行之前编译为本机代码,以提高性能。
本地库(Native Library)是由C/C++源码编译后的动态库文件,其编译是C/C++源码根据其要运行的目标平台的指令集翻译成对应的机器码的过程,不同的处理器架构,需要编译出相应平台的动态库,才能被正确的执行。因此为了让app能在不同的处理器平台上都能正确的运行,一般app都会将其C/C++源文件为常见平台(armeabi,armeabi-v7a等)都编译出相应的本地库文件,在打包成apk文件时,将这些不同平台的库都打包进apk的lib子目录中,每一种abi存放一个目录,目录名为abi的类型名。因此,一个apk文件的lib子目录中就可能同时包含多种abi库文件情况,当一个用户在自己的设备上安装该app时,系统就需要根据自己的所支持的abi类型,为app选择适当abi类型的库文件进行安装,以确保app在系统上正常运行。
Java本地调用。Java Native Interface(JNI)标准成为Java平台的一部分,它允许Java代码和其他语言的代码进行交互。
JNI明确分开了Java代码与本机代码(C/C++)的执行,定义了一个清晰的API在这两者之间进行通信。很大程度上来说,它避免了本机代码对JVM的直接内存引用过,从而确保本机代码只需编写一次,并且可以跨不同的JVM实现或版本运行。
借助JNI,本机代码可以随意与Java对象交互,获取或设置字段值,以及调用方法,而不会像Java代码中的相同功能那样受到诸多限制。但也有缺点:它牺牲了Java代码的安全性,换取了完成上述所列任务的能力。在应用陈故乡中使用JNI提供了强大的、对机器资源(内存、I/O等)的低级访问,因此不会像普通Java开发人员那样受到安全网的保护。
一些主要的Java技术,如JDBC和RMI,大部分都采用JNI方式实现。但是,采用JNI确实会影响程序的平台无关性,所以只能在特别需要的地方才能使用。通常来说,如果遇到下面的情况,我们可以考虑JNI:
●需要直接操作物理设备,而没有相关的驱动程序,这时候我们可能需要用C甚至汇编语言来编写该设备的驱动,然后通过JNI调用;
●涉及大量数学运算的部分,用Java会带来些效率上的损失;
●用Java会产生系统难以支付的开销,如需要大量网络链接的场合;
●存在大量可重用的C/C++代码,通过JNI可以减少开发工作量,避免重复开发。
⚠️在利用JNI技术的时候要注意以下几点:
●由于Java安全机制的限制,不要试图通过Jar文件的方式发布包含本地化方法的Applet到客户端;
●注意内存管理问题,虽然在本地方法返回 Java 后将自动释放局部引用,但过多的局部引用将使虚拟机在执行本地方法时耗尽内存;
●JNI技术不仅可以让Java程序调用C/C++代码,也可以让C/C++代码调用Java代码。
dll already loaded in another classloader解决方法
错误原因:
Java虚拟机为了在JNI本地库中确保基于classloader的命名空间隔离,因而不允许一个JNI本地库被两个不同的classloader加载。
每个web应用都有一个专属的classloader,这样多个应用时,就出现两个classloader加载同一JNI本地库的情况。
解决方法:
将含有JNI调用的jar包部署在Web服务器的公用lib库中,如将其放入的 tomcat/bin,tomcat/common/lib,jdk/bin,jdk/jre/ext/lib等目录下。
Java是一个统称,它包括丰富的内容,并且还在不断地扩展当中。
1、Java语言规范(语法)
2、Java虚拟机(JVM)及可运行于JVM之上的其他编程语言
3、JDK,包容Java基础类库和各种开发工具
4、Java相关应用开发技术与开源项目:Java EE,android,spring,netty等
编译型和解释型语言;Java是一个混合类型的编程语言,跨平台,运行在JVM中,源代码是标准的文本文件,被编译为字节码,运行时再被转换为机器指令。
JRE(Java runtime environment):包容JVM以及运行Java程序的其他基础设施(比如基类库),没有它就不可能在Windows等操作系统上运行Java程序。
JDK全称:Java SE development kit
JDK=JRE+相关开发工具(如javac)
如需开发Java程序,必须安装JDK
只需运行编译好的Java程序,安装JRE即可
编写Java程序通常经历5个阶段:
1、Edit(编辑):程序员书写代码并保存在磁盘上
2、Compile(编译):编译器生成字节码(bytecode)
3、Load(装入):类装载器(class loader)在内存中保存字节码
4、Verify(校验):校验器Verifier保证字节码不违反安全规则
5、Execute(执行):解释器将字节码翻译成机器码
Git是目前世界上最先进的分布式版本控制(Version control)系统。
相对于集中式版本控制系统,分布式版本控制系统没有“中央服务器”,每个人的电脑都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上。比方说你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。
分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了。相反集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。
举个例子,当你在写长篇大论时,完成了第一个阶段,然而你突然灵光乍现,想到一个更好段落来取代以前写的其中一段,但你又不确定以后会不会又改回来,所以你只能保存原来的副本,重开一个文档写。最后决定选哪个。然而当要修改的地方太多时,你就会有许多副本,以至于你自己都不知道哪个文件修改了哪个地方。
Git就是用来解决这个问题的。
它不但能自动帮我记录每次文件的改动,还可以让同事协作编辑,这样就不用自己管理一堆类似的文件了,也不需要把文件传来传去。如果想查看某次改动,只需要在软件里查看即可。