您的位置:首页技术开发JSP 学院 → Java JNI的实践与分析

Java JNI的实践与分析

时间:2009/8/23 12:09:00来源:本站整理作者:我要评论(0)

       Java 环境和语言对于应用程序开发来说是非常安全和高效的。但是,一些应用程序却需要执行纯 Java 程序无法完成的一些任务,比如:

  与旧有代码集成,避免重新编写。

  实现可用类库中所缺少的功能。举例来说,在 Java 语言中实现ping 时,您可能需要 Internet Control Message Protocol (ICMP) 功能,但基本类库并未提供它。

  最好与使用C/C++ 编写的代码集成,以充分发掘性能或其他与环境相关的系统特性。

  解决需要非Java 代码的特殊情况。举例来说,核心类库的实现可能需要跨包调用或者需要绕过其他 Java 安全性检查。

  JNI 允许您完成这些任务。它明确分开了 Java 代码与本机代码(C/C++)的执行,定义了一个清晰的 API 在这两者之间进行通信。从很大程度上说,它避免了本机代码对 JVM 的直接内存引用,从而确保本机代码只需编写一次,并且可以跨不同的 JVM 实现或版本运行。

  借助 JNI,本机代码可以随意与 Java 对象交互,获取和设计字段值,以及调用方法,而不会像 Java 代码中的相同功能那样受到诸多限制。这种自由是一把双刃剑:它牺牲 Java 代码的安全性,换取了完成上述所列任务的能力。在您的应用程序中使用 JNI 提供了强大的、对机器资源(内存、I/O 等)的低级访问,因此您不会像普通 Java 开发人员那样受到安全网的保护。JNI 的灵活性和强大性带来了一些编程实践上的风险,比如导致性能较差、出现 bug 甚至程序崩溃。您必须格外留意应用程序中的代码,并使用良好的实践来保障应用程序的总体完整性。

  本文介绍JNI 用户最常遇到的10 大编码和设计错误。其目标是帮助您认识到并避免它们,以便您可以编写安全、高效、性能出众的JNI 代码。本文还将介绍一些用于在新代码或已有代码中查找这些问题的工具和技巧,并展示如何有效地应用它们。

  Java JNI 编程缺陷可以分为两类

  性能:代码能执行所设计的功能,但运行缓慢或者以某种形式拖慢整个程序。

  正确性:代码有时能正常运行,但不能可靠地提供所需的功能;最坏的情况是造成程序崩溃或挂起。

  性能缺陷

  程序员在使用 JNI 时的 5 大性能缺陷如下:

  不缓存方法 ID、字段 ID 和类

  触发数组副本

  回访(Reaching back)而不是传递参数

  错误认定本机代码与 Java 代码之间的界限

  使用大量本地引用,而未通知 JVM

  不缓存方法 ID、字段 ID 和类

  要访问 Java 对象的字段并调用它们的方法,本机代码必须调用 FindClass()、GetFieldID()、GetMethodId() 和 GetStaticMethodID()。对于 GetFieldID()、GetMethodID() 和 GetStaticMethodID(),为特定类返回的 ID 不会在 JVM 进程的生存期内发生变化。但是,获取字段或方法的调用有时会需要在 JVM 中完成大量工作,因为字段和方法可能是从超类中继承而来的,这会让 JVM 向上遍历类层次结构来找到它们。由于 ID 对于特定类是相同的,因此您只需要查找一次,然后便可重复使用。同样,查找类对象的开销也很大,因此也应该缓存它们。

  举例来说,清单 1 展示了调用静态方法所需的 JNI 代码:

  清单 1. 使用 JNI 调用静态方法

  int val=1;

  jmethodID method;

  jclass cls;

  cls = (*env)->FindClass(env, "com/ibm/example/TestClass");

  if ((*env)->ExceptionCheck(env)) {

  return ERR_FIND_CLASS_FAILED;

  }

  method = (*env)->GetStaticMethodID(env, cls, "setInfo", "(I)V");

  if ((*env)->ExceptionCheck(env)) {

  return ERR_GET_STATIC_METHOD_FAILED;

  }

  (*env)->CallStaticVoidMethod(env, cls, method,val);

  if ((*env)->ExceptionCheck(env)) {

  return ERR_CALL_STATIC_METHOD_FAILED;

  }

  当我们每次希望调用方法时查找类和方法 ID 都会产生六个本机调用,而不是第一次缓存类和方法 ID 时需要的两个调用。

相关视频

    没有数据

相关阅读 jdk不是有效的win32程序怎么办 jdk不是有效的win32程序解决方法java设置cookie教程 java怎么设置cookiejava怎么设置随机数 java设置随机数详细教程java怎么设置光标位置 java设置光标位置教程如何在Mac上清除Java高速缓存?如何在Mac上卸载Java?Mac上怎么卸载Java?OSX 10.11 java 6不兼容问题解决办法如何为Mac更新Java?java mac版更新教程

文章评论
发表评论

热门文章 没有查询到任何记录。

最新文章 Java中Servlet获得异步 Java中Servlet获得异步支持java递归实现文件的删除和拷贝innerHTML怎样失焦判断FreeMarker和Jsp的应用范围

人气排行 java如何远程登录linux并执行其命令教你用jsp写反弹的shellFreeMarker和Jsp的应用范围Java 7关于#的用法jsp统计在线人数代码Java短信发送机的实现如何用java连接数据库方法Java中Servlet获得异步支持