资源是在附加的堆栈跟踪中获取的,但从未发布过。内存泄漏

时间:2015-05-06 07:53:13

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

如果我注释掉方法(* a) - > CallVoidMethod(a,b,meth,“FROM JNI”); 该应用程序不会崩溃,否则崩溃。

假设我没有释放可能导致内存泄漏的资源“jstr”,那么为什么只有在CallVoidMethod()时才会发生?

我该怎么做才能解决这个问题? 感谢所有花时间写下解决方案或阅读本文的人

ERROR:

  

android.process.acore E / StrictMode:在附加的堆栈跟踪中获取资源但从未发布。有关避免资源泄漏的信息,请参阅java.io.Closeable   java.lang.Throwable:显式终止方法'close'未调用

这是我原生的“C”代码......

#include "com_example_prabhu_helloworldnative_HelloWorld.h"
#include <jni.h>
#include <android/log.h>

#define  LOG_TAG    "testjni"
#define  ALOG(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)

JNIEXPORT jstring JNICALL Java_com_example_prabhu_helloworldnative_HelloWorld_HelloJNI(JNIEnv *a, jobject b)
{
    //jstring jstr = (*a)->NewStringUTF(a, "This comes from jni....");
    jclass clazz =(*a)->GetObjectClass(a, b);
    jmethodID meth = (*a)->GetMethodID(a, b, "messageMe", "(Ljava/lang/String;)V");
    __android_log_print(ANDROID_LOG_DEBUG, "LOG_TAG", "\n this is log messge \n");
    ALOG("Hello World");
    if(meth == 0)
    {
        return;
    }

    (*a)->CallVoidMethod(a, b, meth, "FROM JNI");
    //(*a)->Release
    ALOG("REACHING HERE");

    return (*a)->NewStringUTF(a, "APXOR");
}

2 个答案:

答案 0 :(得分:1)

StrictMode仅报告发布StrictMode明确监视的对象的失败。它没有触发,因为你无法从JNI释放字符串。在堆栈跟踪指示的代码中分配的对象需要在最后一次引用之前通过显式close()调用释放。如果在关闭对象之前将其丢弃并最终确定,则系统会报告错误。

您调用的方法可能与失败的对象有关,也可能没有任何关系 - 它可能只是做分配导致GC更快发生,因此您的应用会立即报告错误而不是这样做后面。

在此问题中包含更多logcat输出可能会有用。严格模式代码通常配置为发出警告...如果您的应用实际上崩溃,则问题可能与关闭资源失败无关。

您的代码可能存在的一个问题是误用b。您将其传递给GetMethodID(),其中jclass作为其第二个参数;因为那显然有用,我希望&#39; b&#39;成为一个班级。如果在Java代码中声明HelloJNI方法static,则会出现这种情况。 (你打电话给GetObjectClass(a,b),但忽略了结果。)既然如此,通过&#39; b&#39;因为CallVoidMethod()的第二个参数可能是错误的,并且会导致失败。

此外,如另一个答案所述,当需要char*时,您无法传递C字符串或jstring。 &#34;来自JNI&#34;必须转换为NewStringUTF的jstring。编译器应警告这一点。

启用CheckJNI后,我希望报告一个JNI错误,这会导致应用程序被终止。

答案 1 :(得分:0)

我认为你必须自己创建Java字符串:

...
jstring str = env->NewStringUTF("FROM JNI");
(*a)->CallVoidMethod(a, b, meth, str);
env->DeleteLocalRef(str);
...