我们应该从JNI电话中不做任何事情吗?这些是什么?
例如,我需要使用一个C ++库,它可以阻止和阻止I / O调用
在这些情况下,我应该注意一些警告吗?我也知道脚本提供相同的功能(虽然不确定实际的脚本语言)。这会是一个更好的选择(从Java
调用脚本)吗?如果是,为什么?
答案 0 :(得分:1)
除非您使用GetPrimitiveArrayCritical
and GetStringCritical
,否则JNI不会限制您可以通过多种方式执行的操作:
调用
GetPrimitiveArrayCritical
后,本机代码不应该 在呼叫之前运行一段时间ReleasePrimitiveArrayCritical
。我们必须处理这对内的代码 功能在“关键区域”中运行。里面一个关键 区域,本机代码不得调用其他JNI函数或任何系统 调用可能导致当前线程阻塞并等待另一个线程 Java线程。 (例如,当前线程不能调用a上的读取 流由另一个Java线程写入。)
否则你几乎可以自由地做你想做的事情,禁止改变JVM和操作系统交互方式的东西(比如replacing the JVM signal handlers)。
您还会询问是否应该运行脚本而不是直接调用本机函数。如果你不知道C ++库究竟会做什么,那么执行外部进程会更安全,但它也不太方便(你需要建立一种通信方式),而且可能比在同一个进程中调用更慢。 / p>
答案 1 :(得分:1)
根据我的个人经验,糟糕的想法是使用比平常更大的第三方库作为黑盒子,不知道究竟是什么在其中。线程,I / O,硬件API访问,长时间运行的JNI调用,最糟糕的是,自定义内存管理(而不是标准的lib malloc / free)。可能会出现毛病,包括JVM在奇怪的地方报告内存泄漏和异常,和/或无法解释的崩溃。有了这样一个库(巨大的OpenGL引擎),我们不得不剖析并采用外部过程方法。它通过命名管道进行通信,速度惊人。要采取的教训:始终知道本机库在底层做了什么,这对于JAR来说并不是那么需要。