应该如何利用JNI技术提高Java的性能详解

JNI实现流程图

1. 首先编写需要JNI功能的Java类源文件。其中,需要JNI实现的方法应当用native关键字声明。在该类中,用System. loadLibrary()方法加载需要的动态链接库。关键代码如下:

//Compute.java

……

public class Compute {

public native double comp (double [] params);

……

static {

// 调用动态链接库

System. loadLibrary(“mathlib”);

}

……

}

2. 将该类源文件用Java类编译器编译成二进制字节码文件。由于采用了native关键字声明,编译器会忽视没有代码体的JNI方法部分。

3. 利用javah -jni *.class 生成相关JNI方法的头文件。我们能手工生成该文件,不过由于Java虚拟机是根据一定的命名规范完成对JNI方法的调用,所以手工编写头文件需要特别小心。

上述文件产生的头文件部分代码如下:

//Compute. h

……

extern “C” {

JNIEXPORT jdouble JNICALL Java_Compute_comp (JNIEnv *, jobject, jdoubleArray);

}

……

能看出,JNI函数名称分为三部分:首先是Java关键字,供Java虚拟机识别;然后是调用者类名称(全限定的类名,其中用下划线代替名称分隔符);最后是对应的方法名称,各段名称之间用下划线分割。

JNI函数的参数也由三部分组成: 首先是JNIEnv *,是个指向JNI运行环境的指针;第二个参数随本地方法是静态还是非静态而有所不同——非静态本地方法的第二个参数是对对象的引用,而静态本地方法的第二个参数是对其 Java 类的引用; 其余的参数对应通常 Java 方法的参数,参数类型需要根据一定规则进行映射。

4. 根据头文件编写相应方法的实现代码。由于篇幅所限,具体的实现部分在此不再赘述。在编码过程中,需要注意变量的长度问题,例如Java的整型变量长度为32位,而C语言为16位,所以要仔细核对变量类型映射表,防止在传值过程中出现问题。

5. 利用C/C++编译器将JNI实现代码编译成动态链接库。调用者类中需要显式调用该链接库。

在Win32环境下,能利用Visual C ++或其他能产生DLL文件的C/C++编译器将实现代码编译成动态链接库。笔者利用的是Microsoft.NET Framework的编译器。编译指令如下,其中%Java_HOME%是笔者的jdk安装目录变量:

cl -I%Java_HOME%\include

-I%Java_HOME%\include\win32

-LD jnicomp. c -Femathlib. dll

在Sun Soloaris下,相应指令为:

cc -G -I/usr/local/java/include -I/usr/local/java/include/solaris jnicomp. c \

-o mathlib. so

注意,编译的时候需要用I指令包含必要的库文件路径。

经过上述处理,就基本上完成了一个包含本地化方法的Java类的研发。

JNI技术的应用

一些主要的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代码。

文章来自艾米美甲培训学院 http://www.amysnail.com.cn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值