Взгляните на эту JNI Tips FAQ запись. Он может ответить на ваш вопрос или, по крайней мере, дать вам представление о доступных опциях.
ADDENDUM: (SK9) (Слишком большое поле для комментариев, извините) Соответствующая часть советов JNI приведена ниже. Следуя приведенным здесь указаниям, приложение будет аварийно завершать работу, если массив будет скопирован (что, безусловно, будет) из-за недостатка памяти.
///////////////////
Примитивные массивы
JNI предоставляет функции для доступа к содержимому объектов массива. В то время как массивы объектов должны быть доступны по одной записи за раз, массивы примитивов могут быть прочитаны и записаны напрямую, как если бы они были объявлены в C.
Чтобы сделать интерфейс максимально эффективным, не ограничивая реализацию виртуальной машины, семейство вызовов GetArrayElements позволяет виртуальной машине либо возвращать указатель на фактические элементы, либо выделять некоторую память и делать копию. В любом случае возвращаемый необработанный указатель гарантированно будет действительным до тех пор, пока не будет выполнен соответствующий вызов Release (что означает, что, если данные не были скопированы, объект массива будет закреплен и не может быть перемещен в рамках сжатия куча). Вы должны освободить каждый массив, который вы получаете. Кроме того, в случае сбоя вызова Get вы должны убедиться, что ваш код не пытается позднее освободить указатель NULL.
Вы можете определить, были ли данные скопированы, передавая ненулевой указатель для аргумента isCopy. Это редко полезно.
Вызов Release принимает аргумент режима, который может иметь одно из трех значений. Действия, выполняемые виртуальной машиной, зависят от того, вернула ли она указатель на фактические данные или их копию:
0
Фактически: объект массива не закреплен.
Копировать: данные копируются обратно. Буфер с копией освобождается.
JNI_COMMIT
Фактически: ничего не делает.
Копировать: данные копируются обратно. Буфер с копией не освобождается.
JNI_ABORT
Фактически: объект массива не закреплен. Ранее записи не прерываются.
Копировать: буфер с копией освобождается; любые изменения в нем будут потеряны.
Одна из причин проверки флага isCopy - узнать, нужно ли вам вызывать Release с JNI_COMMIT после внесения изменений в массив - если вы чередуетесь между внесением изменений и выполнением кода, использующего содержимое массива, вы можете пропустить неоперативный коммит. Другая возможная причина для проверки флага - для эффективной обработки JNI_ABORT. Например, вы можете получить массив, изменить его на месте, передать части другим функциям, а затем отменить изменения. Если вы знаете, что JNI делает новую копию для вас, нет необходимости создавать еще одну «редактируемую» копию. Если JNI передает вам оригинал, вам нужно сделать свою собственную копию.
Некоторые утверждают, что вы можете пропустить вызов Release, если * isCopy равен false. Это не вариант. Если буфер копирования не выделен, то исходная память должна быть закреплена и не может быть перемещена сборщиком мусора.
Также обратите внимание, что флаг JNI_COMMIT НЕ освобождает массив, и вам в конечном итоге потребуется снова вызвать Release с другим флагом. "