Управление памятью потока JNI Attach/Detach

У меня есть обратный вызов JNI:

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

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

Когда я запускаю его таким образом (пустой полезный код), я получаю утечку памяти. Если я закомментирую весь метод, утечки не будет. Как правильно прикрепить/отсоединить нити?

Мое приложение обрабатывает звуковые данные в реальном времени, поэтому потоки, ответственные за обработку данных, должны быть выполнены как можно скорее, чтобы быть готовыми к следующему пакету. Поэтому для этих обратных вызовов я создаю новые потоки. Каждую секунду их десятки, а то и сотни, они прикрепляются к JVM, вызывают callback-функцию, которая перерисовывает граф, отсоединяются и умирают. Это правильный способ сделать это? Как справиться с утечкой памяти?

РЕДАКТИРОВАТЬ: опечатка

ОК. Я создал минимальный необходимый код:

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, я получаю обычный пилообразный шаблон, утечки нет. Максимальное использование кучи составило около 5 МБ. Тем не менее, наблюдение за проводником процессов действительно показывает какое-то странное поведение: память медленно растет и растет, 4 КБ в секунду в течение минуты или около того, а затем внезапно вся эта выделенная память падает. Эти дропы не соотносятся со сборкой мусора (они происходят реже и освобождают меньше памяти, чем те пилы в профилировщике).

Таким образом, я считаю, что это некое поведение ОС, обрабатывающее десятки тысяч потоков, живущих в миллисекундах. Есть ли у какого-нибудь гуру объяснение этому?

13
задан Jakub Zaverka 13 March 2012 в 14:39
поделиться