我有一個JNI回調:JNI連接/斷開線程內存管理
void callback(Data *data, char *callbackName){
JNIEnv *env;
jvm->AttachCurrentThread((void **)&env, NULL);
/* start useful code*/
/* end useful code */
jvm->DetachCurrentThread();
}
當我運行像這樣(空有用的代碼),我得到了內存泄漏。如果我評論整個方法,就沒有泄漏。什麼是附加/分離線程的正確方法?
我的應用程序處理實時聲音數據,所以負責數據處理的線程必須儘快完成,以便爲另一批准備。所以對於這些回調,我創建了新線程。每秒鐘有幾十個甚至幾百個,他們自己附加到JVM上,調用一個回調函數來重繪圖形,分離和死亡。這是做這件事的正確方法嗎?如何處理泄漏的內存?
編輯:錯字
OK我已經創建需要mimimal代碼:
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,然後突然所有分配的內存都下降了。這些滴與垃圾收集不符(它們發生的次數少,並且釋放的內存少於探查器中的鋸齒)。
所以我最好的選擇是,它是一些操作系統行爲處理幾萬毫秒的線程。有些大師對此有解釋嗎?有關從本機代碼回調到Java
我明白你的意思,我通常會同意。我創建的線程真的很短暫。我創建它們(使用WinApi CreateThread),然後立即將它們附加到JVM。在Java中,他們使用新值重繪Swing圖形。當它們完成時,它們分離並停止執行(返回0),此時它們應該被操作系統銷燬。它們被用來爲Java傳遞一個新的值。每個聲道每秒約有40個聲道(我可以使用多達32個聲道)。 – 2012-03-10 16:31:17
你可能會考慮線程池。讓你的線程停留更長時間並從隊列中接受輸入,而不是不斷地產生新的線程。這將減少OS和Java中的線程管理開銷。 – technomage 2012-03-12 15:23:30
如果除了調用方法之外,您在JNI中執行任何Java內容,您可能還希望圍繞這些操作推送/彈出本地框架。 – technomage 2012-03-12 15:24:37