我有一个本地C库,它可以在非常大的数据集上运行一些算法(大约数百MB到几GB)。这是使用JNA在Java框架内调用的。 Java加载数据并通过JNA将它传递给C库。
问题是,似乎使用了过多的内存。对于一个数据集,在Java端完成所有加载并且C库使用2.0gb(使用内部内存管理确定)后,进程使用约3.0gb。但是,一旦C库被调用,这个过程最终会达到9.5GB!
具体问题,然后:
Java和C端没有重叠吗?也就是说,JNA是否生成Java数据的C有效副本(顺便说一下,所有int和double数组),并将其传递给本地库,而不是包含Java中数据的相同块?
即使假定没有重叠,并且本地库使用JVM中包含的数据的副本,那么额外的4.5GB来自哪里?这大约是进程占用的系统内存数量的两倍,我无法想象它会发生什么。关于JNA的这些方面的文档似乎非常有限,但我想知道是否有人比我更熟悉JNA,可能知道为什么它会使用如此之多的内存,以及如何以及如何能够减少其占用空间。
编辑:启用JNA的Java类看起来像这样:
public interface MyNativeLibrary extends Library {
MyNativeLibrary INSTANCE = (MyNativeLibrary) Native.loadLibrary(
"native_library", MyNativeLibrary.class);
int native_library_function(int num_inputs, int inputs[], int max_num_outputs, int preallocated_outputs[]);
}在这种情况下,本机函数的返回值将是返回的输出数或错误代码。 C接口用int32_t指定,以确保大小匹配。