今天终于搞定困扰我一周的一个问题了。
我们的算法通过jni封装,在java调用的时候总是随机的crash掉,具体的位置在jvm里面,应该可以肯定是jvm做垃圾回收的时候死掉的。但是并不知道是在回收哪块内存出的问题,所以也就无从知道死的具体原因了。我们的程序是在jni层创建了一些java对象,然后返回给java层,大体结构像下面代码一样,我只能基本判断是我们的jni层在创建对象的时候(也就是createInfo函数)出问题了,至于具体什么问题,我也不清楚。
public class Test {
public class Info {
public int x;
public int y;
public Info() {
x = 0;
y = 0;
}
}
public native Info createInfo();
// ...
}
因为我对java不是很熟悉,所以只好一边学,一边弄。最初就是在local/glbal reference这些概念上下功夫,来回的读jni的specification,也没有发现自己的问题。后期又学着使用一些java的调试工具,比如jhat啊,hpjmeter啊,但是仍然没有什么头绪。上周一周,就在这个问题上不断的尝试,也没结果。
今天终于发现了问题所在,其实说来也很简单。jni要创建的那些返回对象,是作为内部类定义的,所以在构造的时候需要传一个外层类实例才能初始化。也就是说,虽然看上去Info类的构造函数是无参数的,但实际上它是有一个隐含参数的,相当于Info(Test outer)。如果在java层构造这个对象,那么outer参数会被自动传入,但我们在jni层构造,就需要自己传入这个参数了。如果没有给出这个参数,jni编译运行都没有问题,但实际上,它是用了一个未知的对象(就是在栈里面的一个随机值)来作为这个outer参数的,所以当这个对象需要释放的时候(一般也就是在垃圾回收的时候)就会crash了。
现在想起来,其实这个问题我原来曾经有过一次小遭遇,那时我在使用有参数构造函数来创建一个内部嵌套类,发现构造出来的对象值是错掉的。其实就是因为少传了一个outer参数啊,但是当时我没有去解决这个问题,而是绕过问题,采用构造函数无参数,然后在创建之后,再手工给每个数据字段赋值的方法。这样虽然表面上也达到了目的,但是隐藏了问题。
事实一次次的告诉我们,遇到问题一定要解决。就算你暂时绕过这个问题,但早晚它还会出来的。
http://space.itpub.net/67063/viewspace-478328
分享到:
相关推荐
一个C++(Ubuntu16.04+QT5.9.1)通过JNI,调用JAVA类及方法的示例。通过JNI传递和返回多种类型的参数,boolean ,int,String,ArrayList<string>,ArrayList嵌套ArrayList<ArrayList<String>>等。
<br>Common Object Request Broker Architecture (CORBA) <br>JDBC Technology <br>Servlets <br>Chapter 5: Java Native Interface (JNI) Technology <br><br>JNI Example <br>Strings and Arrays <br>Other ...
ReadTestquestion<br>7.5. 课程设计作业<br>第8章 日历记事本<br>8.1. 设计内容<br>8.2. 设计要求<br>8.3. 总体设计<br>8.4. 具体设计<br>8.4.1. 运行效果与程序发布<br>8.4.2. 主类CalendarPad<br>8.4.3. 记事本...
<br>1、很早以前就针对Oracle 8里面的Express Server作了开发,当时是使用dml的C接口,在Java<br><br>里面通过JNI访问,虽然只有一个命令接口,但是着实费力,同时JNI对J2EE Application <br><br>Server也有所影响。...
AndroidJNI <=> 安卓本地编程接口 AndroidJNIHelper <=> 安卓本地接口辅助类 Animation <=> 动画 AnimationClip <=> 动画剪辑 AnimationClipPair <=> 动画剪辑对 AnimationCurve <=> 动画曲线 AnimationEvent ...
ava.exe -X 参数信息<br><br>-X参数是非标准参数。<br> -Xmixed 混合模式执行 (默认)<br> -Xint 只用解释模式执行<br>...<br> -Xrs 减少java虚拟机使用操作系统指令 (见文档)<br> -Xcheck:jni 为JNI函数执行附加的检测
返回硬盘序列号<br><br><br>ChenminDiskIDTest.bat 将启动直接演示一个读取硬盘序列号的测试<br>测试读取硬盘序列号的源代码在ChenminDiskIDTest.jar中<br><br>需要JNI源代码的请直接QQ联系281284015<br><br>
JNI,全称Java Native Interface,是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互。JNI在很多场景下都是必要的,比如调用操作系统本地库、加速性能关键的代码或者实现与硬件设备的直接通信。在...
install <ServerName><ShowName><JarName>[<JVM>] remove: service remove remove <ServerName> Example: -install -ServerName JNISvr -ShowName "JNI服务" -JarName App.jar -JVM "-Xms64m -Xmx256m\" -...
其中,[options] 是可选参数,<classes> 是要转换的 Java 类文件的名称。 javah 命令提供了多种选项,包括: * -help:显示帮助信息 * -classpath <path>:指定类文件的搜索路径 * -bootclasspath <path>:指定...
如 List<People> out=new ArrayList<>(); Search.searchPeople("小明".toCharArray(),0.1f,out); 支持同音字搜索 如:搜“晓民”也能搜出“小明” searchPeopleByLetter(String letter,List<People> out)首字母...
<value>org.apache.hadoop.fs.ceph.CephFileSystem</value> </property> <property> <name>ceph.conf.file</name> <value>/etc/ceph/ceph.conf</value> </property> ``` 此外,可能还需要修改`hadoop-env.sh`,`...
#include <jni.h> #include <string.h> JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_getStringFromJNI(JNIEnv *env, jobject thiz) { return (*env)->NewStringUTF(env, "Hello from JNI!...
molindo-mysql-collations-lib JNI桥接到libmysqlclient(MySQL的C客户端API)提供MySQL基于归类的比较功能... <artifactId>molindo-mysql-collations-lib</artifactId> <version>0.1.0</version> </dependency>
same as input if not specify-f overwrite output directory if already exists-x <ext> header file extension (default: .hpp)-c <ext> source file extension (default: .cpp)-p <prefix> macro prefix-s ...
jniloader 简单的(对于最终用户)本机库加载器。... < artifactId>jniloader</ artifactId> < version>1.1</ version> </ dependency> 快照分布在Sonatype的快照存储库中: < dependency> < groupId>com.githu
<artifactId>gkt3-jni</artifactId> <version>0.6.2</version> </dependency> ``` 接下来,安装Glade界面设计器,它是用于设计GTK界面的工具。在Ubuntu/Debian上: ```bash sudo apt-get install glade ``` 在...
当需要通过子类对象调用父类的特定方法时,可以使用 `CallNonvirtual<TYPE>Method` 函数。这允许子类对象直接调用父类的方法,即使该方法在子类中已经被重写。 - **步骤**: 1. 获取父类的 `jclass`。 2. 获取父类...
#include <jni.h> #include <android/log.h> #include <string> extern "C" JNIEXPORT jstring JNICALL Java_com_example_yourapp_MainActivity_getMacAddress(JNIEnv *env, jobject /* this */) { std::string ...
<artifactId>maven-nativetools-plugin</artifactId> <version>0.0.7</version> <executions> <execution> <id>generate-native-header</id> <goals> <goal>javah</goal> </goals> </execution> </...