2015-05-06 2 views
0

Если я прокомментирую метод (* a) -> CallVoidMethod (a, b, meth, "FROM JNI"); Приложение не терпит крах, иначе оно сработает.Ресурс был получен при подключенной трассировке стека, но не был выпущен. утечка памяти

Предполагая, что я не выпустил ресурс «jstr», который мог вызвать утечку памяти, тогда почему это происходит только тогда, когда CallVoidMethod()?

Что мне делать для решения этой проблемы? Спасибо всем, кто тратит свое время на написание вниз решение или чтение через эту

ОШИБКА:

android.process.acore E/StrictMode﹕ A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
java.lang.Throwable: Explicit termination method 'close' not called

Это мой родной «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"); 
} 

ответ

1

StrictMode сообщает только о сбоях для освобождения объектов, которые явно контролируются StrictMode. Он не срабатывает, потому что вы не можете выпустить строку из JNI. Объект, выделенный в точке в коде, указанном трассировкой стека, должен быть освобожден с явным вызовом close() до того, как последняя ссылка на него будет удалена. Если объект отбрасывается и завершается до его закрытия, система сообщает об ошибке.

Метод, который вы вызываете, может иметь или не иметь ничего общего с провальным объектом - он может просто делать распределения, которые заставляют GC работать раньше, поэтому ваше приложение сообщает об ошибке немедленно, а не делает это позже ,

Включение большего количества выходных данных logcat в ваш вопрос может быть полезным здесь. Код строгого режима обычно настроен для выдачи предупреждений ... если ваше приложение на самом деле сбой проблема может не быть связана с неспособностью закрыть ресурс.

Одна из возможных проблем с вашим кодом - неправильное использование b. Вы передаете его GetMethodID(), который принимает jclass в качестве второго аргумента; поскольку, по-видимому, это работает, я бы ожидал, что «b» будет классом. Это будет иметь место, если метод HelloJNI был объявлен static в коде Java. (Вы вызываете GetObjectClass(a,b), но игнорируете результат.) В этом случае передача «b», поскольку второй аргумент CallVoidMethod(), вероятно, неверен и приведет к ошибке.

Далее, как указано в другом ответе, вы не можете передать строку C или char*, если требуется jstring. «FROM JNI» должен быть преобразован в jstring с NewStringUTF. Компилятор должен предупредить об этом.

С включенной функцией CheckJNI я ожидаю сообщения об ошибке JNI, что убивает приложение.

+0

ВЫ РЕШАЛИ МОЮ ПРОБЛЕМУ :) –

0

Я думаю, что вы необходимо создать Java-строку самостоятельно:

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

Пробовал, чтобы это не сработало, поэтому я прокомментировал в коде –