flo*_*w2k 3 java java-native-interface native
我在概念上并不清楚 Java 何时使用 JNI。文献1,2似乎建议使用 JNI 是可选的 - 它对于我自己现有的本机 C 应用程序来说是一个有用的功能,但最好尽可能避免使用它:\nLiang 指出“记住,一旦应用程序使用JNI,它可能会失去[可移植性和安全性]的两个好处”。
\n\n然而,我在 SDK 中查看了 Oracle 的 API 实现,我public static native void arraycopy在java/lang/System.java. 问题:
任何 Java API 实现都需要系统调用,所以如果我是正确的,似乎无法避免与本机代码的交互。
\n\n1:Horstmann,核心 Java 第 2 卷
\n2。梁,Java\xe2\x84\xa2 Native Interface Programmer\xe2\x80\x99s 指南和规范
您列出了 JNI 的两个缺点——可移植性和安全性。实际上,还有另外一个,在日常生活中更重要:JNI 调用会带来显着的性能成本,因为它们会影响全局 JVM 状态并锁定一些 JVM 功能,包括 GC。
正如另一个答案中详细介绍的,JVM 确实依赖于 JNI。但这并不是一个完整的答案。
您的 JVM 可能支持快速 JNI 方法(例如 Android ART 就支持)。这些方法保证快速且无阻塞,并且可以在不更改状态的情况下执行它们,请参见@FastNative。Java SDK 本机方法大量使用此类改进,因此它们不会遭受传统 JNI 的性能成本。
这些本机方法在运行期间不依赖LoadLibrary()。这消除了 JNI 的另一个显着性能成本 - 在运行时加载和“绑定”本机方法。运行时绑定的最大风险是它在由类加载器确定的任意时间发生,并且可能与 JVM 或应用程序当时必须执行的其他紧急操作发生冲突。与系统本机方法无关。
此外,可移植性问题也无关紧要:Java 运行时是为每个受支持的平台精心设计的,它本身并不是“可移植的”,只有在其之上运行的 Java 应用程序才是“可移植的”。
最后, JNI 的安全风险是双重的:JNI 不受私有声明的限制,并且本机代码可能会执行危险的操作,危及在同一 JVM 中运行的任何类或应用程序。而且,从第三方库加载时,JNI 代码可能会被黑客攻击(例如,更改操作系统环境就足以导致System.loadLibrary()加载欺诈者版本的库)。系统本机方法不会受到此类攻击。
简而言之,即使 JVM 确实使用了 JNI,但这也不能成为你自己的类不加区别地使用 JNI 的借口。
| 归档时间: |
|
| 查看次数: |
290 次 |
| 最近记录: |