我遇到 JNI 程序随机内存不足的问题。
这是一个 32 位 java 程序,它读取文件,进行一些图像处理,通常使用 250MB 到 1GB。然后,所有这些对象都会被丢弃,然后程序对 JNI 程序进行一系列调用,通常需要 100-250MB。
当交互运行时,我从未见过问题。但是,当运行对许多文件连续执行此操作的批处理操作时,JNI 程序将随机耗尽内存。它可能在一两个文件上出现内存问题,然后在接下来的 10 个文件上运行良好,然后再次出现故障。
我在 JNI 调用之前转储了可用内存量,它遍布整个地图,有时 100MB,有时 800MB。我的解释是,Java 垃圾收集有时会在图像处理后立即运行,有时则不会。如果不是,则可能没有足够的内存用于 JNI 程序。
我已经阅读了所有关于 GC 是非确定性的、不应该调用它、不会产生任何区别等的内容,但看起来在开始 JNI 调用之前强制 GC 确实会改善这种情况。
但有没有办法真正确保有一定量的空闲内存才能继续呢?
要回答有关JNI程序的问题,该程序是由另一家公司提供的,我对它如何分配内存没有真正的了解。我所知道的是它是用c++编写的,它没有垃圾收集。我被告知它需要 100-250MB 的内存,我看到的数字也证实了这一点。
也许我应该将问题改写为:如果我要进行一个我知道需要 250MB 内存的 JNI 调用,我如何确保它有那么多可用内存?
确实,一种可能的解决方案是进行 64 位构建。然而,这个批处理操作是 32 位构建上的 QA 的一部分,所以我想测试真实的东西。
我自己解决这个问题的方法就是简单地调用System.gc()
,但是从inside本机代码:
#include <jni.h>
// ...
int my_native_function(JNIEnv* env, jobject obj) {
jclass systemClass = nullptr;
jmethodID systemGCMethod = nullptr;
// ...
// Take out the trash.
systemClass = env->FindClass("java/lang/System");
systemGCMethod = env->GetStaticMethodID(systemClass, "gc", "()V");
env->CallStaticVoidMethod(systemClass, systemGCMethod);
}
我希望这对你也有用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)