JNI释放内存以避免内存泄漏

时间:2009-10-07 18:32:56

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

所以我有这个从我的Java程序通过JNI调用的C ++程序,代码如下:

    JNIEXPORT jstring JNICALL Java_com_entrust_adminservices_urs_examples_authn_LdapAuthenticator2_takeInfo(JNIEnv *env, jobject obj, jstring domain, jstring id, jstring idca, jstring password) 
{
    const char *nt_domain;
    const char *nt_id;
    const char *nt_password;
    HANDLE hToken = 0;

    bool aut = false;

    nt_domain = env->GetStringUTFChars(domain, NULL);
    nt_id = env->GetStringUTFChars(id, NULL);
    nt_password = env->GetStringUTFChars(password, NULL);

      aut = LogonUser(nt_id, nt_domain, nt_password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &hToken );

      /* release buffers */
    env->ReleaseStringUTFChars(domain, nt_domain);
    env->ReleaseStringUTFChars(id, nt_id);
    env->ReleaseStringUTFChars(password, nt_password);
    /* release the login handle */
    CloseHandle(hToken);

    if(aut)
    {
        return env->NewStringUTF("true"); 
    }

    DWORD dwError = GetLastError();
      LPVOID lpMsgBuf;

      FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT ), (LPTSTR) &lpMsgBuf, 0, NULL );

    return env->NewStringUTF((const char*)lpMsgBuf); //returns the contents of lpMsgBuf (error)
}

在第二行到最后一行jstring newString = env->NewStringUTF((const char*)otherString);永远不会被释放,但是返回,是否会导致最终的内存泄漏?无论如何要解决这个问题?

也有可能不是返回一个字符串而是返回一个布尔值(由LogonUser函数返回),而不是一个jstring,而是添加一个“errormessage”引用,在方法中传递,然后更新?我的Java程序能否看到“errormessage”的更新?

感谢。

2 个答案:

答案 0 :(得分:9)

NewStringUTF()创建一个新的java.lang.String - 换句话说,就是Java堆上的一个对象,当没有对它的引用时,它将被收集。

或者您在询问otherString?我不知道FormatMessage做了什么,但看起来它在C堆上分配内存。如果是这样,那么是的,你必须明确释放那个记忆。

有时将otherString设置为常量字符串会让您的生活更加艰难。不要那样做。相反,在if / else的块中调用NewStringUTF(),在第二种情况下释放本机C字符串。

答案 1 :(得分:6)

您不必担心NewStringUTF分配的内存,因为Java垃圾收集器会处理这些内存。

但是你必须释放lpMsgBuf,因为你将FORMAT_MESSAGE_ALLOCATE_BUFFER传递给FormatMessage(即你必须使用LocalFree释放该缓冲区),请参阅FormatMessage文档。