简体   繁体   English

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

[英]JNI Freeing Memory to Avoid Memory Leak

So i have this C++ program that is called via JNI from my Java program, the code follows: 所以我有从我的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)
}

in that second to last line jstring newString = env->NewStringUTF((const char*)otherString); 在第二行到最后一行jstring newString = env->NewStringUTF((const char*)otherString); is never released, but returned, will it cause an eventual memory leak? 永远不会释放,但返回,是否会导致最终的内存泄漏? is there anyway to get around this? 无论如何要绕过这个?

Also is it possible that instead of returning a string i return a boolean (as returned by the LogonUser function), instead of a jstring, and instead add an "errormessage" refrence to be passed in the method, and update that? 也有可能不是返回一个字符串而是返回一个布尔值(由LogonUser函数返回),而不是一个jstring,而是添加一个“errormessage”参考,以便在方法中传递,并更新? will my Java program be able to see an update to "errormessage"? 我的Java程序能否看到“errormessage”的更新?

Thanks. 谢谢。

NewStringUTF() creates a new java.lang.String -- in other words, an object on the Java heap, which will get collected when there are no more references to it. NewStringUTF()创建一个新的java.lang.String - 换句话说,就是Java堆上的一个对象,当没有对它的引用时,它将被收集。

Or are you asking about otherString ? 或者你在询问otherString I don't know what FormatMessage does, but it looks like it's allocating memory on the C heap. 我不知道FormatMessage是做什么的,但看起来它在C堆上分配内存。 If that's the case, then yes, you have to explicitly free that memory. 如果是这样的话,那么是的,你必须明确地释放那个记忆。

You make your life harder by sometimes setting otherString to a constant string. 有时将otherString设置为常量字符串会让您的生活更加艰难。 Don't do that. 不要那样做。 Instead, call NewStringUTF() within the blocks of your if/else, and in the second case free the native C string. 相反,在if / else的块中调用NewStringUTF() ,在第二种情况下释放本机C字符串。

You don't have to worry about the memory allocated by NewStringUTF as that will be taken care of by the Java garbage collector. 您不必担心NewStringUTF分配的内存,因为Java垃圾收集器会处理这些内存。

But you have to free the lpMsgBuf as you are passing FORMAT_MESSAGE_ALLOCATE_BUFFER to FormatMessage (ie you have to use LocalFree to free that buffer), see the FormatMessage documentation. 但是,当您将FORMAT_MESSAGE_ALLOCATE_BUFFER传递给FormatMessage时,您必须释放lpMsgBuf(即您必须使用LocalFree来释放该缓冲区),请参阅FormatMessage文档。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM