2010-01-21 105 views
5

我刚开始与Android NDK工作,但我不断收到SIGSEGV当我有这个电话在我的C代码:在Android中为JNI调用NewObjectArray时会导致SIGSEGV的什么情况?

jobjectArray someStringArray; 
someStringArray = (*env)->NewObjectArray(env, 10, 
(*env)->FindClass(env,"java/lang/String"),(*env)->NewStringUTF(env, "")); 

此基础上所有我能找到的例子,上面的代码是正确的,但我不断收到如果NewObjectArray行被注释掉,SIGSERGV和一切正常。任何想法可能会导致这样的问题?

+0

忘了提及,我正在使用NDK1.6 – Ken 2010-01-21 22:05:31

回答

4

看起来是正确的,所以我猜你已经做了一些其他的错误。我假设你用checkjni运行?你可能想把它分成多行:执行FindClass并检查返回值,执行NewStringUTF并检查返回值,然后调用NewObjectArray。

btw,你可能想传递NULL作为最后一个参数;这种使用空字符串作为数组中每个元素的默认值的模式是常用的(我认为它是从一些Sun文档粘贴的并且从那里传播的副本&),但它很少有用,而且有点浪费。 (并且它与Java中的“new String [10]”的行为不匹配。)

2

我猜其中一个可能的原因是,在长时间运行的JNI方法中,VM在用完每个方法调用本地参考插槽(通常是Android中的512个插槽)。

由于FindClass()和NewStringUTF()函数会分配本地引用,如果您长时间停留在JNI方法中,VM不知道是否应回收特定的本地引用。所以你应该明确调用DeleteLocalRef()来释放不再需要的获取本地引用。如果不这样做,“僵尸”本地引用将占用虚拟机中的插槽,虚拟机在所有本地参考插槽耗尽时中止。

在短期运行的JNI方法中,这可能不是问题,因为所有本地引用在从JNI方法中退出时都会被回收。

相关问题