jni- освобождение массивов объектов

#java #java-native-interface

#java #java-native-interface

Вопрос:

В jni у нас есть GetPrimitiveArrayElements функции для получения указателя на элементы массива в куче и ReleasePrimitiveArrayElements для удаления локальной копии массивов.

однако я передаю массив объектов java в JNI.Эти элементы массива повторяются с помощью GetObjectArrayElement функции для локального jobject.

Но как я могу удалить локальную ссылку на jobject после обработки элементов массива.

Спасибо

Ответ №1:

Независимо от того, были ли jobject захваченные вами массивы изначально выделены на стороне Java или вашим методом JNI, они будут обрабатываться сборкой мусора до тех пор, пока на объекты нет постоянных ссылок. Следовательно, если ваши локальные ссылки на jobject s являются просто локальными переменными, они исчезнут в конце функции, и ваш объект будет иметь право на сборку мусора по обычной причине событий. Если вы сохраните GlobalRef для объектов, то объект все еще будет существовать, а локальная ссылка просто исчезнет, как любая локальная переменная, которой не было выделено место в куче). Если вы сохраняете WeakRef , объект может быть собран из мусора, но если нет, он остается действительным для другого вызова JNI. Сохранение обычной локальной ссылки на jobject во всех вызовах JNI недопустимо.

Кроме того, если вы хотите освободить свою локальную ссылку сразу, а не ждать (например, если бы вы создавали тонну jobject ссылок в одной функции, просто используйте DeleteLocalRef(env, jobj); метод JNIEnv.

В любом случае, документация должна рассказать вам все, что вам нужно знать, если я допустил какие-либо ошибки.

Комментарии:

1. @Nitrex88 Извините. Мой отрицательный отзыв был ошибкой. Я был неправ. Я не могу отменить это, поскольку ваш anwser слишком стар. Отредактируйте это, и я проголосую за.

2. @manuell Отредактировано, но трудно понять, почему вы поддержали бы ответ, который вы описали в своем собственном ответе как «явно неправильный». Не то чтобы это было неправильно.

Ответ №2:

Вы можете либо ничего не делать, либо вызвать DeleteLocalRef() .

Из главы 2 спецификации JNI:

Глобальные и локальные ссылки

JNI разделяет ссылки на объекты, используемые машинным кодом, на две категории: локальные и глобальные ссылки. Локальные ссылки действительны в течение всего времени вызова собственного метода и автоматически освобождаются после возврата собственного метода. Глобальные ссылки остаются действительными до тех пор, пока они не будут явно освобождены.

Объекты передаются собственным методам как локальные ссылки. Все объекты Java, возвращаемые функциями JNI, являются локальными ссылками. JNI позволяет программисту создавать глобальные ссылки из локальных ссылок. Функции JNI, которые ожидают объекты Java, принимают как глобальные, так и локальные ссылки. Собственный метод может возвращать локальную или глобальную ссылку на виртуальную машину в качестве результата.

В большинстве случаев программист должен полагаться на виртуальную машину, чтобы освободить все локальные ссылки после возврата собственного метода. Однако бывают случаи, когда программист должен явно освободить локальную ссылку. Рассмотрим, например, следующие ситуации:

Собственный метод обращается к большому объекту Java, тем самым создавая локальную ссылку на объект Java. Затем собственный метод выполняет дополнительные вычисления, прежде чем вернуться к вызывающей стороне. Локальная ссылка на большой объект Java предотвратит сбор мусора из объекта, даже если объект больше не используется в оставшейся части вычисления. Собственный метод создает большое количество локальных ссылок, хотя не все из них используются одновременно. Поскольку виртуальной машине требуется определенный объем пространства для отслеживания локальной ссылки, создание слишком большого количества локальных ссылок может привести к нехватке памяти в системе. Например, собственный метод перебирает большой массив объектов, извлекает элементы в виде локальных ссылок и оперирует с одним элементом на каждой итерации. После каждой итерации программисту больше не нужна локальная ссылка на элемент массива.

JNI позволяет программисту вручную удалять локальные ссылки в любой точке собственного метода. Чтобы гарантировать, что программисты могут вручную освобождать локальные ссылки, функциям JNI не разрешается создавать дополнительные локальные ссылки, за исключением ссылок, которые они возвращают в результате.

Локальные ссылки допустимы только в том потоке, в котором они созданы. Машинный код не должен передавать локальные ссылки из одного потока в другой.