JNI附加/分离线程内存管理 [英] JNI Attach/Detach thread memory management

查看:92
本文介绍了JNI附加/分离线程内存管理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个JNI回调:

void callback(Data *data, char *callbackName){
    JNIEnv *env;
    jvm->AttachCurrentThread((void **)&env, NULL);
    /* start useful code*/

    /* end useful code */
    jvm->DetachCurrentThread();
}

当我这样运行它(空的有用代码)时,我得到一个记忆泄漏。如果我注释掉整个方法,就没有泄漏。附加/分离线程的正确方法是什么?

When I run it like this (empty useful code), I get a memory leak. If I comment out the whole method, there is no leak. What is the correct way of attaching / detaching threads?

我的应用程序处理实时声音数据,因此负责数据处理的线程必须尽快完成为了准备另一批。所以对于这些回调,我创建了新的线程。它们每秒都有几十甚至几百个,它们将自己附加到JVM,调用一个重新绘制图形,分离和死亡的回调函数。这是做这件事的正确方法吗?如何处理泄漏的内存?

My application processes real-time sound data, so the threads responsible for data processing must be done as soon as possible in order to be ready for another batch. So for these callbacks, I create new threads. There are dozens or even hundreds of them each second, they attach themselves to JVM, call a callback function which repaints a graph, detach and die. Is this a correct way of doing this stuff? How to handle the leaking memory?

编辑:错字

好的我已经创建了一个所需的mimimal代码:

OK I have created a mimimal code needed:

package test;

public class Start
{
    public static void main(String[] args) throws InterruptedException{
        System.loadLibrary("Debug/JNITest");
        start();
    }

    public static native void start();
}

#include <jni.h>
#include <Windows.h>
#include "test_Start.h"

JavaVM *jvm;
DWORD WINAPI attach(__in  LPVOID lpParameter);

JNIEXPORT void JNICALL Java_test_Start_start(JNIEnv *env, jclass){
    env->GetJavaVM(&jvm);
    while(true){
        CreateThread(NULL, 0, &(attach), NULL, 0, NULL);
        Sleep(10);
    }
}


DWORD WINAPI attach(__in  LPVOID lpParameter){
    JNIEnv *env;
    jvm->AttachCurrentThread((void **)&env, NULL);
    jvm->DetachCurrentThread();
    return 0;
}

当我运行VisualJM分析器时,我得到了通常的锯齿模式,没有在那里泄漏。堆使用率达到5MB左右。然而,观察进程资源管理器确实显示出一些奇怪的行为:内存缓慢上升和上升,4K一秒钟一分钟左右然后突然所有这些分配的内存下降。这些丢弃与垃圾收集不相符(它们发生频率较低,并且比分析器中的锯齿更少释放内存)。

and when I run the VisualJM profiler, I get the usual sawtooth pattern, no leak there. Heap usage peaked at around 5MB. However, observing the process explorer indeed shows some weird behaviour: memory is slowly rising and rising, 4K a second for a minute or so and then suddenly all this allocated memory drops. These drops do not correspond with garbage collection (they occur less often and deallocate less memory than those saw-teeth in the profiler).

所以我最好的选择是它是一些操作系统行为处理数万个生命线程。有些大师对此有解释吗?

So my best bet is that it is some OS behaviour handling tens of thousands milisecond-lived threads. Does some guru have an explanation for this?

推荐答案

我想出了问题所在。它是悬挂在我没有销毁的JNI代码中的本地引用。每个回调都会创建一个新的本地引用,从而导致内存泄漏。当我将本地引用转换为全局时,我可以重用它,问题就消失了。

I figured the problem. It was dangling local references in the JNI code I didn't destroy. Every callback would create a new local reference, thus resulting in a memory leak. When I converted the local reference to global, so I could reuse it, the problem disappeared.

这篇关于JNI附加/分离线程内存管理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆