【问题标题】:How to know whether it is a memory leak or not when calling native code in Java?在Java中调用本机代码时如何知道是否是内存泄漏?
【发布时间】:2012-01-04 12:24:41
【问题描述】:

我在 main 中调用了一个本地函数,它在一个 while 循环中。

public static void main (String[] args) throws Throwable {

        testDLL test = new testDLL();
        String ar[];
        while (true){
            System.out.println("Memory before garbage collection: " + Runtime.getRuntime().freeMemory());           
            ar = test.GetSomething("###");      
            test.finalize();
            System.gc();
            Thread.sleep(5000);
            System.out.println("Memory after garbage collection: " + Runtime.getRuntime().freeMemory());
            System.out.println();
        }
}

以下程序的输出是:(运行大约 1 分钟)

Memory before garbage collection: 1915288
Memory after garbage collection: 1915136

Memory before garbage collection: 1915136
Memory after garbage collection: 1914984

Memory before garbage collection: 1914984
Memory after garbage collection: 1916624

Memory before garbage collection: 1916624
Memory after garbage collection: 1916472

Memory before garbage collection: 1916472
Memory after garbage collection: 1916320

Memory before garbage collection: 1916320
Memory after garbage collection: 1916168

Memory before garbage collection: 1916168
Memory after garbage collection: 1916624

Memory before garbage collection: 1916624
Memory after garbage collection: 1916472

我猜这不是内存泄漏。但是当我打开 Windows 的任务管理器时,进程 javaw.exe 的大小不断增加(每次迭代 100 KB)。想知道它是内存泄漏还是我应该忽略它?或者这是否意味着本机函数中存在内存泄漏?

仅供参考,我已经仔细检查了我的本机函数是否存在任何内存泄漏!

谢谢!

编辑:

原生函数:

JNIEXPORT jobjectArray JNICALL Java_testDLL_GetSomething
(JNIEnv * env, jobject jobj, jstring approvedJString){

    const int num = 100;

    jboolean * isCopy;
    jobjectArray serialNumArrJobj;
    const char* approved = env->GetStringUTFChars(approvedJString, isCopy);
    string serialNumArr[num];

    //*
    *   Long lengthy code here
    *   Populates the string array "serialNumArr"
    *//

    // ========

    env->ReleaseStringUTFChars(approvedJString, approved);
    env->DeleteLocalRef(approvedJString);
    env->DeleteLocalRef(jobj);

    ////////////

    int i, sizeOfArr = 0;

    for( i = 0; i < num; i++) {
        if (serialNumArr[i].empty())
            break;
        else
            sizeOfArr++;
    }

    serialNumArrJobj = (jobjectArray)env->NewObjectArray(sizeOfArr,
         env->FindClass("java/lang/String"),
         env->NewStringUTF(""));


    for( i = 0; i < sizeOfArr; i++) {
        env->SetObjectArrayElement(serialNumArrJobj,
            i,
            env->NewStringUTF(serialNumArr[i].c_str()));
    }

    return serialNumArrJobj;
}

【问题讨论】:

  • 请。也发布你的原生函数。
  • @Azodious 实际上很长。我在 C++ 中使用 WMI。但我可以发布使用 jni 变量的部分。 :)
  • 我没有看到内存使用有太大变化。似乎保持相对稳定。我错过了什么吗?
  • 您是否尝试过使用 Profiler 并分析对象创建、实时实例等?
  • @CarlZulauf:我已经粘贴了原生函数。请检查一下。

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


【解决方案1】:

您的期望是错误的。你不能指望System.gc() 不仅仅是对垃圾收集器的提示,而自己调用finalize() 是完全错误的。

【讨论】:

  • 我猜你没有仔细阅读问题,问题不在java端,即使我删除finalize()System.gc()仍然有一些内存泄漏!
【解决方案2】:

我认为您需要编写像 Java 代码一样直接调用本机代码的单元测试,例如 Mock 测试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多