JNI,我找不到内存泄漏的代码位置

时间:2018-09-27 07:14:25

标签: java c++ java-native-interface

这是jni cpp附带代码:

JNIEXPORT jfloatArray JNICALL Java_server_framework_chat_similarity_TextMatcher_xgboostBatchScore
      (JNIEnv *env, jobject obj, jlong long_h, jobject q1, jobject q2){

        jclass ret = env->FindClass("java/util/ArrayList");
        jclass java_util_ArrayList = static_cast<jclass>(env->NewGlobalRef(ret));
        jmethodID java_util_ArrayList_ = env->GetMethodID(java_util_ArrayList, "<init>", "(I)V");
        jmethodID java_util_ArrayList_size = env->GetMethodID (java_util_ArrayList, "size", "()I");
        jmethodID java_util_ArrayList_get = env->GetMethodID(java_util_ArrayList, "get", "(I)Ljava/lang/Object;");
        jmethodID java_util_ArrayList_add = env->GetMethodID(java_util_ArrayList, "add", "(Ljava/lang/Object;)Z");

        jint len = env->CallIntMethod(q1, java_util_ArrayList_size);
        vector<string> result1;
        result1.reserve(len);
        for (jint i=0; i<len; i++) {
          jstring element = static_cast<jstring>(env->CallObjectMethod(q1, java_util_ArrayList_get, i));
          const char* pchars = env->GetStringUTFChars(element, NULL);
          result1.push_back(pchars);
          env->ReleaseStringUTFChars(element, pchars);
          env->DeleteLocalRef(element);
        }  

        jint len2 = env->CallIntMethod(q2, java_util_ArrayList_size);
        vector<string> result2;
        result2.reserve(len2);
        for (jint i=0; i<len2; i++) {
          jstring element = static_cast<jstring>(env->CallObjectMethod(q2, java_util_ArrayList_get, i));
          const char* pchars = env->GetStringUTFChars(element, NULL);
          result2.push_back(pchars);
          env->ReleaseStringUTFChars(element, pchars);
          env->DeleteLocalRef(element);
        }  

        HANDLE_XGBOOST_SESSION h = (HANDLE_XGBOOST_SESSION)long_h;
        vector<float> scores = get_xgboost_batch_score(h, result1, result2);

        jfloatArray result = env->NewFloatArray(len);
        jfloat fill[len];
        for (int i = 0; i < scores.size(); i++) {
             fill[i] = scores[i]; 
        }
        env->SetFloatArrayRegion(result, 0, len, fill);

        env->DeleteLocalRef(ret);
        env->DeleteGlobalRef(java_util_ArrayList);
        env->DeleteLocalRef(q1);
        env->DeleteLocalRef(q2);
        return result;
      }

get_xgboost_batch_score的含义是:批量获取两个文本的匹配分数。

我启动了5个简单的Java测试程序,其中包含一个while循环来运行此代码。

内存监视器显示内存在30分钟内减少了约50M。

但是我尽力而为,找不到错误代码。

我使用valgrind跟踪Java程序并找到:

==13595== Invalid write of size 4
==13595==    at 0x80CC692: ???
==13595==    by 0x80B84E6: ???
==13595==    by 0x64CB649: ??? (in /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-3.b13.el7_5.x86_64/jre/lib/amd64/server/libjvm.so)
==13595==    by 0x64DE14E: ??? (in /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-3.b13.el7_5.x86_64/jre/lib/amd64/server/libjvm.so)
==13595==    by 0x64E92B2: ??? (in /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-3.b13.el7_5.x86_64/jre/lib/amd64/server/libjvm.so)
==13595==    by 0x767A3C5A: JNIEnv_::CallIntMethod(_jobject*, _jmethodID*, ...) (jni.h:987)

CallIntMethod是错误吗?

1 个答案:

答案 0 :(得分:0)

没有内存泄漏。

大约5小时后内存不会减少。

no memory leak