gpt4 book ai didi

java - 有什么方法可以释放通过 JNI/JNA 绑定(bind) C 代码而生成的 Java 代码中的内存?

转载 作者:太空宇宙 更新时间:2023-11-04 01:22:35 25 4
gpt4 key购买 nike

我正在使用一个使用 JNA 绑定(bind)到原始 C 库的 java 库(该库称为 Leptonica)。我遇到了一种情况,必须在 C 代码中调用 free(data) 来释放内存。但是,Java 中有什么函数可以释放内存吗?

在C代码中

void ImageData::SetPixInternal(Pix* pix, GenericVector<char>* image_data) {
l_uint8* data;
size_t size;
pixWriteMem(&data, &size, pix, IFF_PNG);
pixDestroy(&pix);
image_data->init_to_size(size, 0);
memcpy(&(*image_data)[0], data, size);
free(data);
}

函数 pixWriteMem() 将创建内存并将其分配给“数据”,稍后您需要执行 free(data) 以释放内存。

在 Java 代码中,我只能访问 pixWriteMem(),而不能访问 SetPixInternal(),因此我无法释放“数据”,这会造成内存泄漏。

最佳答案

这里的其他评论和回答似乎都在暗示你只依赖垃圾收集器或者告诉垃圾收集器运行。对于在 C 中分配并通过 JNI 在 Java 中使用的内存,这不是正确答案。

看起来 execution() 确实释放了内存。您向我们展示的最后一行是 free(data)。不过,要回答您提出的问题,答案是“不直接”。如果你有能力添加到 C 代码,你可以创建另一个 C 函数来释放数据,然后使用 JNI 调用它。也许还有更多我们没有看到的与您对内存泄漏的担忧更相关?

此外,在释放由您正在使用的库分配的内存时要小心。在尝试释放它之前,您应该确保该库不再需要它并且正在泄漏它。

现在回到一般的内存管理...

Java 确实是一种垃圾收集语言。这意味着您不会专门删除对象。相反,您确保没有对它的引用,然后垃圾收集器负责内存管理。这并不意味着 Java 没有内存泄漏,因为有一些方法可以意外地保留引用,从而使对象永远不会被垃圾收集。如果您遇到这种情况,您可能需要阅读 the different kinds of references in Java (strong/weak/etc.) .

同样,这不是这里的问题。这是一个 C/Java 混合体,有问题的代码在 C 中,被 Java 调用。在 C 中,您分配要使用的内存,然后在用完后需要自己释放 内存。即使 C 代码由 Java 通过 JNI 运行,您仍需对自己的内存负责。您不能只是 malloc() 一堆内存并期望 Java 垃圾收集器知道何时清理它。因此,OP 的问题。

如果您需要自己添加功能来执行free,即使没有 C 部分的源代码,您仍然可以编写自己的 C 接口(interface)来释放内存,如果您可以访问指向相关内存的指针。您基本上可以编写一个小型库,它只为您释放内存,为它创建 JNI 接口(interface),然后将指针传递给它。如果你走这条路,那么,根据你的操作系统,你可能需要保证你的小型免费库的 native 代码与 native 代码的其余部分在同一进程中运行,或者如果不是同一进程,那么至少该进程您运行它对其他代码进程拥有的内存具有写访问权限;这个内存/进程问题在你的情况下可能不是问题,但为了完整性我把它扔在那里。

关于java - 有什么方法可以释放通过 JNI/JNA 绑定(bind) C 代码而生成的 Java 代码中的内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38337195/

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