를 부착 내가 JNI 콜백이 :이 (빈 유용한 코드)처럼 실행하면JNI가/분리 스레드 메모리 관리
void callback(Data *data, char *callbackName){
JNIEnv *env;
jvm->AttachCurrentThread((void **)&env, NULL);
/* start useful code*/
/* end useful code */
jvm->DetachCurrentThread();
}
, 나는 메모리 누수를 얻을. 전체 방법을 주석 처리하면 누수가 없습니다. 스레드를 연결/분리하는 올바른 방법은 무엇입니까?
내 응용 프로그램은 실시간 사운드 데이터를 처리하므로 다른 배치를 준비하려면 데이터 처리를 담당하는 스레드를 가능한 한 빨리 완료해야합니다. 따라서 이러한 콜백을 위해 새 스레드를 만듭니다. 매 초마다 수십 또는 수백 개의 JVM이 있고 그래프를 다시 그린 콜백 함수를 호출하고 분리하고 죽습니다. 이게이 일을하는 올바른 방법일까요? 누출 된 메모리를 처리하는 방법?
편집 : 오타
내가 필요한 mimimal 코드를 만든 OK :
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에서 최고를 기록했습니다. 그러나 프로세스 탐색기를 실제로 관찰하는 것은 이상한 행동을 보여줍니다. 메모리가 천천히 상승하고 상승하며, 1 분 동안 4K를 1 초마다 실행 한 다음 갑자기이 할당 된 메모리를 모두 삭제합니다. 이러한 드랍스는 가비지 콜렉션과 일치하지 않습니다 (프로파일 링의 톱니보다 메모리가 덜 자주 할당되고 할당량이 줄어 듭니다).
내 최선의 방법은 수만 밀리 세컨드 스레드를 처리하는 일부 OS 동작입니다. 어떤 전문가는 이에 대한 설명이 있습니까? 네이티브 코드에서 다시 자바로 호출에 대한
나는 귀하의 요지를 볼 수 있으며, 나는 보통 동의합니다. 내가 만들고있는 스레드는 실제로 수명이 짧습니다. 나는 (WinApi CreateThread를 사용하여) 그것들을 만들고, 즉시 그들을 JVM에 붙인다.Java에서는 Swing 그래프를 새 값으로 다시 그립니다. 작업이 완료되면 분리되어 실행을 중지합니다 (0을 반환).이 시점에서 OS에 의해 파기되어야합니다. 그것들은 Java에 새로운 가치를 전달하는 데 사용됩니다. 각 사운드 채널에 대해 약 초당 약 40 개가 있습니다 (최대 32 개 채널로 작업합니다). –
스레드 풀링을 고려할 수 있습니다. 새 스레드를 지속적으로 생성하는 대신 스레드를 오래 머무르게하고 큐에서 입력을받습니다. 이렇게하면 OS와 Java에서 스레드 관리 오버 헤드가 줄어 듭니다. – technomage
JNI에서 메소드를 호출하는 것 외에 다른 Java 작업을 수행하는 경우 해당 작업을 중심으로 로컬 프레임을 푸시/팝 할 수도 있습니다. – technomage