0

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

这不会返回到 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”就可以每秒调用数百次,这就是我认为它很快耗尽内存的原因。

获取有关诊断错误的信息的任何帮助都会很棒,因为此时我在日志猫中什么也看不到。

更新:我的旧 main 和 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;
  }

我的新 main 和 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();
4

1 回答 1

-1

完成后您不会释放字符串,因此每次调用都会泄漏它。

于 2012-11-15T20:54:14.297 回答