`
netcome
  • 浏览: 482253 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JNI的crash终于搞定<转>

    博客分类:
  • JAVA
阅读更多

今天终于搞定困扰我一周的一个问题了。

我们的算法通过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

分享到:
评论

相关推荐

    JNI与C++数据类型传递示例(包括ArrayList对象、ArrayList嵌套返回)

    一个C++(Ubuntu16.04+QT5.9.1)通过JNI,调用JAVA类及方法的示例。通过JNI传递和返回多种类型的参数,boolean ,int,String,ArrayList&lt;string&gt;,ArrayList嵌套ArrayList&lt;ArrayList&lt;String&gt;&gt;等。

    Advanced Programming for the Java 2 Platform.chm

    &lt;br&gt;Common Object Request Broker Architecture (CORBA) &lt;br&gt;JDBC Technology &lt;br&gt;Servlets &lt;br&gt;Chapter 5: Java Native Interface (JNI) Technology &lt;br&gt;&lt;br&gt;JNI Example &lt;br&gt;Strings and Arrays &lt;br&gt;Other ...

    java应用软件程序设计

    ReadTestquestion&lt;br&gt;7.5. 课程设计作业&lt;br&gt;第8章 日历记事本&lt;br&gt;8.1. 设计内容&lt;br&gt;8.2. 设计要求&lt;br&gt;8.3. 总体设计&lt;br&gt;8.4. 具体设计&lt;br&gt;8.4.1. 运行效果与程序发布&lt;br&gt;8.4.2. 主类CalendarPad&lt;br&gt;8.4.3. 记事本...

    Oracle Olap开发备忘录

    &lt;br&gt;1、很早以前就针对Oracle 8里面的Express Server作了开发,当时是使用dml的C接口,在Java&lt;br&gt;&lt;br&gt;里面通过JNI访问,虽然只有一个命令接口,但是着实费力,同时JNI对J2EE Application &lt;br&gt;&lt;br&gt;Server也有所影响。...

    unity5圣典中文API手册v0.02.chm

    AndroidJNI &lt;=&gt; 安卓本地编程接口 AndroidJNIHelper &lt;=&gt; 安卓本地接口辅助类 Animation &lt;=&gt; 动画 AnimationClip &lt;=&gt; 动画剪辑 AnimationClipPair &lt;=&gt; 动画剪辑对 AnimationCurve &lt;=&gt; 动画曲线 AnimationEvent ...

    java虚拟机参数

    ava.exe -X 参数信息&lt;br&gt;&lt;br&gt;-X参数是非标准参数。&lt;br&gt; -Xmixed 混合模式执行 (默认)&lt;br&gt; -Xint 只用解释模式执行&lt;br&gt;...&lt;br&gt; -Xrs 减少java虚拟机使用操作系统指令 (见文档)&lt;br&gt; -Xcheck:jni 为JNI函数执行附加的检测

    用JAVA读取硬盘序列号

    返回硬盘序列号&lt;br&gt;&lt;br&gt;&lt;br&gt;ChenminDiskIDTest.bat 将启动直接演示一个读取硬盘序列号的测试&lt;br&gt;测试读取硬盘序列号的源代码在ChenminDiskIDTest.jar中&lt;br&gt;&lt;br&gt;需要JNI源代码的请直接QQ联系281284015&lt;br&gt;&lt;br&gt;

    JNI处理hashmap,string等对象的操作

    JNI,全称Java Native Interface,是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互。JNI在很多场景下都是必要的,比如调用操作系统本地库、加速性能关键的代码或者实现与硬件设备的直接通信。在...

    Windows服务启动调用Java App --附vc6源码

    install &lt;ServerName&gt;&lt;ShowName&gt;&lt;JarName&gt;[&lt;JVM&gt;] remove: service remove remove &lt;ServerName&gt; Example: -install -ServerName JNISvr -ShowName "JNI服务" -JarName App.jar -JVM "-Xms64m -Xmx256m\" -...

    android NDK 自动生成jni头文件

    其中,[options] 是可选参数,&lt;classes&gt; 是要转换的 Java 类文件的名称。 javah 命令提供了多种选项,包括: * -help:显示帮助信息 * -classpath &lt;path&gt;:指定类文件的搜索路径 * -bootclasspath &lt;path&gt;:指定...

    android-jni基于c语言实现的姓名模糊搜索so库

    如 List&lt;People&gt; out=new ArrayList&lt;&gt;(); Search.searchPeople("小明".toCharArray(),0.1f,out); 支持同音字搜索 如:搜“晓民”也能搜出“小明” searchPeopleByLetter(String letter,List&lt;People&gt; out)首字母...

    ceph上搭建hadoop

    &lt;value&gt;org.apache.hadoop.fs.ceph.CephFileSystem&lt;/value&gt; &lt;/property&gt; &lt;property&gt; &lt;name&gt;ceph.conf.file&lt;/name&gt; &lt;value&gt;/etc/ceph/ceph.conf&lt;/value&gt; &lt;/property&gt; ``` 此外,可能还需要修改`hadoop-env.sh`,`...

    AndroidJNI技术实现

    #include &lt;jni.h&gt; #include &lt;string.h&gt; JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_getStringFromJNI(JNIEnv *env, jobject thiz) { return (*env)-&gt;NewStringUTF(env, "Hello from JNI!...

    molindo-mysql-collations-lib:JNI桥接到MySQL的基于归类的比较功能

    molindo-mysql-collat​​ions-lib JNI桥接到libmysqlclient(MySQL的C客户端API)提供MySQL基于归类的比较功能... &lt;artifactId&gt;molindo-mysql-collations-lib&lt;/artifactId&gt; &lt;version&gt;0.1.0&lt;/version&gt; &lt;/dependency&gt;

    j2n:从 Java 存档文件 (.jar) 生成 C++JNI 包装器

    same as input if not specify-f overwrite output directory if already exists-x &lt;ext&gt; header file extension (default: .hpp)-c &lt;ext&gt; source file extension (default: .cpp)-p &lt;prefix&gt; macro prefix-s ...

    jniloader:轻量级的便利,可加载JNI本机

    jniloader 简单的(对于最终用户)本机库加载器。... &lt; artifactId&gt;jniloader&lt;/ artifactId&gt; &lt; version&gt;1.1&lt;/ version&gt; &lt;/ dependency&gt; 快照分布在Sonatype的快照存储库中: &lt; dependency&gt; &lt; groupId&gt;com.githu

    使用Eclipse+Glade在Linux下进行Java的GTK程序开发

    &lt;artifactId&gt;gkt3-jni&lt;/artifactId&gt; &lt;version&gt;0.6.2&lt;/version&gt; &lt;/dependency&gt; ``` 接下来,安装Glade界面设计器,它是用于设计GTK界面的工具。在Ubuntu/Debian上: ```bash sudo apt-get install glade ``` 在...

    java与c++交互(JNI学习笔记)

    当需要通过子类对象调用父类的特定方法时,可以使用 `CallNonvirtual&lt;TYPE&gt;Method` 函数。这允许子类对象直接调用父类的方法,即使该方法在子类中已经被重写。 - **步骤**: 1. 获取父类的 `jclass`。 2. 获取父类...

    android jni获取 Mac地址

    #include &lt;jni.h&gt; #include &lt;android/log.h&gt; #include &lt;string&gt; extern "C" JNIEXPORT jstring JNICALL Java_com_example_yourapp_MainActivity_getMacAddress(JNIEnv *env, jobject /* this */) { std::string ...

    新建maven工程,简单的java jni demo,mvn package生成jar文件,用于测试linux上的jni开发

    &lt;artifactId&gt;maven-nativetools-plugin&lt;/artifactId&gt; &lt;version&gt;0.0.7&lt;/version&gt; &lt;executions&gt; &lt;execution&gt; &lt;id&gt;generate-native-header&lt;/id&gt; &lt;goals&gt; &lt;goal&gt;javah&lt;/goal&gt; &lt;/goals&gt; &lt;/execution&gt; &lt;/...

Global site tag (gtag.js) - Google Analytics