【发布时间】:2012-03-09 23:49:00
【问题描述】:
我有一个 JNI 回调:
void callback(Data *data, char *callbackName){
JNIEnv *env;
jvm->AttachCurrentThread((void **)&env, NULL);
/* start useful code*/
/* end useful code */
jvm->DetachCurrentThread();
}
当我像这样运行它(空的有用代码)时,我遇到了内存泄漏。如果我注释掉整个方法,就没有泄漏。连接/分离线程的正确方法是什么?
我的应用程序处理实时声音数据,因此负责数据处理的线程必须尽快完成,以便为下一批做好准备。所以对于这些回调,我创建了新线程。每秒有几十个甚至几百个,它们将自己附加到 JVM,调用一个回调函数来重新绘制图形,分离并死亡。这是做这些事情的正确方法吗?内存泄露如何处理?
编辑:错字
好的,我已经创建了所需的最小代码:
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 java-native-interface