Что происходит с несколькими ссылками на один и тот же объект в JNI?

#java-native-interface

#java-native-interface

Вопрос:

Я использую JNI для доступа к некоторому Java-коду из C . Ссылки на объекты, возвращаемые JNI, должны быть очищены, но что произойдет, если несколько методов вернут один и тот же объект Java? Нужно ли вызывать Delete для каждого из них?

Например, java.nio.Buffer имеет метод clear() , который очищает буфер и возвращает себя.

Если я сначала создаю буфер с помощью JNI, а затем вызываю clear() , нужно ли мне очищать оба jobjects , или я могу очистить только один из них?

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

1. ‘Ссылки на объекты, возвращаемые JNI, должны быть очищены’: нет. Все они будут освобождены при возврате метода JNI. Возможно, вам потребуется освободить их заранее, если вы используете много, но обычно в этом нет необходимости.

2. В моем случае использования у меня заканчивается счетчик локальных ссылок перед возвратом.

3. Итак, в этом случае вам нужно их освободить. Самый простой способ — ограничить их с помощью методов API локального фрейма. Когда вы освобождаете фрейм, все, что в нем содержится, освобождается. Автоматически включаются дубликаты.

4. @user207421 Я знаю, что есть дополнительные помощники, которые помогают управлять ссылками, но в этом случае мне приходится делать это вручную.

5. Если вы можете запускать свой код на Android, вы можете использовать dumpReferenceTables метод android.os.Debug до и после вызова clear() . Он помечен @hide , но вы можете вызвать его через отражение или JNI.

Ответ №1:

В JNI у вас есть объекты Java и ссылки на объекты Java. A jobject — это ссылка на объект, которая указывает на объект Java и которую вы можете освободить, DeleteLocalRef если она вам больше не нужна.

Вызов clear() Buffer объекта создаст новую ссылку для возвращаемого объекта, даже если он фактически указывает на тот же объект. Так что да, если у вас закончились локальные ссылки, вы должны освободить все ссылки на ваш Buffer , кроме той, с которой вы работаете.