gpt4 book ai didi

java - 使用导向器跨 C++ 和 Java 的 SWIG 多态性中的内存泄漏

转载 作者:太空狗 更新时间:2023-10-29 21:49:16 34 4
gpt4 key购买 nike

我有一个 C++ 程序可以从网络接收二进制数据。接收到数据后,它会将数据以字节数组的形式从 C++ 回调到 Java 客户端。我使用 SWIG 中的 director 功能轻松实现跨 C++ 和 Java 的跨语言多态性以进行回调。这是 a link .

但我发现 SWIG 中没有从 C++ 中的 char* 到 Java 中的 byte[] 的类型映射。所以,我给 virous.i 添加了一个补丁。这是 a link .

/*Director specific typemaps*/
%typemap(directorin, descriptor="[B") char *BYTE {
jbyteArray jb = (jenv)->NewByteArray(strlen(BYTE));
(jenv)->SetByteArrayRegion(jb, 0, strlen(BYTE), (jbyte*)BYTE);
$input = jb;
}
%typemap(directorout) char *BYTE {
$1 = 0;
if($input){
$result = (char *) jenv->GetByteArrayElements($input, 0);
if(!$1)
return $null;
jenv->ReleaseByteArrayElements($input, $result, 0);
}
}
%typemap(javadirectorin) char *BYTE "$jniinput"
%typemap(javadirectorout) char *BYTE "$javacall"

例如。我在 C++ 中有一个名为 A 的类:

class A{
public:
virtual void onDataReceived(const char* BYTE, const size_t len) {}
};

然后在 Java 代码中我有另一个类 B 来扩展 A:

class B extends A {
@Override
public void onDataReceived(byte[] data, long len) {
//handling the data.
}
}

我可以在 Java 代码中接收字节数组,但它似乎永远不会被 JVM 垃圾回收。 SWIG 生成的包装文件中的 onDataReceived 方法是这样的:

void SwigDirector_A::onDataReceived(char const *BYTE, size_t const len) {
JNIEnvWrapper swigjnienv(this);
JNIEnv * jenv = swigjnienv.getJNIEnv();
jobject swigjobj = (jobject) NULL;
jbyteArray jBYTE = 0;
jlong jlen;

if (!swig_override[3]) {
A::onDataReceived(BYTE,len);
return;
}
swigjobj = swig_get_self(jenv);
if (swigjobj && jenv->IsSameObject(swigjobj, NULL) == JNI_FALSE) {
{
jbyteArray jb = (jenv)->NewByteArray(strlen(BYTE));
(jenv)->SetByteArrayRegion(jb, 0, strlen(BYTE), (jbyte*)BYTE);
jBYTE = jb;
}
jlen = (jlong) len;
jenv->CallStaticVoidMethod(Swig::jclass_DataTransferJNI, Swig::director_methids[3], swigjobj, jBYTE, jlen);
if (jenv->ExceptionCheck() == JNI_TRUE) return;
} else {
SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null upcall object");
}
if (swigjobj) jenv->DeleteLocalRef(swigjobj);
}

在我的 C++ 代码中,我会在回调完成后删除接收缓冲区中的数据。但是我从 Java VisualVM 上查到,java 客户端进程使用的内存在很长一段时间后没有被 GC-ed。提前感谢您的帮助!

附言。数据量很大,大约有 32KB。

最佳答案

我通过在 Director 类型映射中添加删除对 j​​b 的引用解决了这个问题:(jenv)->DeleteLocalRef(jb);

这是 updated patch .

关于java - 使用导向器跨 C++ 和 Java 的 SWIG 多态性中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8602908/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com