У меня есть собственная библиотека C, которая запускает некоторые алгоритмы для очень больших наборов данных (порядка сотен мегабайт в гб).Это вызывается из среды Java с использованием JNA.Java загружает данные и передает их через JNA в библиотеку C.
Проблема в том, что, похоже, используется чрезмерное количество памяти.Для одного набора данных процесс использует около 3,0 ГБ после завершения загрузки на стороне Java, а 2,0 ГБ используется библиотекой C (как определено с помощью внутреннего управления памятью).Но процесс, как только вызывается библиотека C, заканчивается с максимальным значением около 9,5 ГБ!
Конкретные вопросы, затем:
Нет ли совпадений между стороной Java и C?То есть, создает ли JNA C-валидную копию данных Java (кстати, все массивы int и double) и передает ее в собственную библиотеку вместо тех же блоков, которые содержат данные в Java?
Даже если предположить, что нет совпадений, и нативная библиотека использует копию данных, содержащихся в JVM, откуда эти дополнительные 4,5 ГБ?Это примерно вдвое увеличивает объем системной памяти, занятой процессом, и я не могу себе представить, где все это происходит.Документация по этим аспектам JNA кажется очень ограниченной, но мне интересно, мог бы кто-нибудь, кто знаком с JNA лучше, чем я, знает, почему он использует так много памяти, и если и как я смогу уменьшить его площадь.
РЕДАКТИРОВАТЬ: Java-класс с поддержкой JNA выглядит следующим образом:
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, чтобы убедиться, что размеры совпадают.