我有一个在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();
答案 0 :(得分:-1)
完成后你就不会释放字符串,所以每次通话都会泄漏它。