本机代码退出时没有错误 - 可能是内存

时间:2012-11-15 20:45:43

标签: android android-ndk java-native-interface

我有一个在c本机代码中调用main函数的线程。

这不会返回java,所以我必须小心内存分配。

main函数调用java上的静态方法作为回调方式。以下是在c:

中实现的方法
void writeat(int x, int y, int style, char *string) {
    JNIEnv *env = getJNIEnv();
    static jmethodID cls_mid = NULL;

    if (cls_mid == NULL) {
        jclass clazz = (*env)->FindClass(env, "com/comp/prod/Kernel");
        cls_mid = (*env)->GetStaticMethodID(env, clazz, "writeat",
                "(IIILjava/lang/String;)V");
    }

    {
        jstring out = (*env)->NewStringUTF(env, string);
        (*env)->CallStaticVoidMethod(env, nullVoid, cls_mid, x, y, style,
                out);
        (*env)->DeleteLocalRef(env, out);
    }
}

这种方法可以使用一段时间,然后在log cat中记录没有任何错误。

如果我评论CallStaticVoidMethod来电,它仍然会这样做。如果我注释掉新的和删除的电话,它就没有问题。

这个字符串“000”每秒被称为数百次,所以这就是为什么我认为它会快速耗尽内存。

获取有关识别错误的信息的任何帮助都会很棒,因为此时我只是在log cat中看不到任何内容。

更新:我的旧主页和getJNIEnv

 JNIEnv *_env;

 JNIEXPORT void JNICALL Java_com_comp_prod_main(JNIEnv *env,
        jclass thiz) {
    LOGV("Main called %d", __LINE__);
    _env = (JNIEnv *) ((*env)->NewGlobalRef(env, env));
      main();
    _env = NULL;
  }

  JNIEnv *getJNIEnv(void) {
     return _env;
  }

我的新主人和getJNIEnv

JavaVM *jvm;

JNIEXPORT void JNICALL Java_com_comp_prod_main(JNIEnv *env,
        jclass thiz) {
    LOGV("Main called %d", __LINE__);
    //this is how to cache it for other threads
    jint rs = (*env)->GetJavaVM(env, &jvm);
    assert (rs == JNI_OK);
    main();
    jvm = NULL;
}

JNIEnv *getJNIEnv(void) {
    JNIEnv *env;
     jint rs = (*jvm)->AttachCurrentThread(jvm, &env, NULL);
     assert (rs == JNI_OK);
     if(env == NULL)
     {
       LOGV("env is NULL");
     }
     return env;
}

从Java调用:

Runnable runTerm = new Runnable() {

public void run() {
  // call main()
  Log.i(TAG, "About to call main on the c!");
  try {
    Terminal.main();
    } catch (IOException e) {
     e.printStackTrace();
    }
    }
};

t = new Thread(runTerm, "C thread");
t.start();

1 个答案:

答案 0 :(得分:-1)

完成后你就不会释放字符串,所以每次通话都会泄漏它。