Ссылки на объекты JNI, полученные через Invocation API: локальные или глобальные? - PullRequest
5 голосов
/ 11 октября 2010

Я использую API вызова JNI, который запускает JVM в программе на Си; в этой ситуации вы получаете указатель JNIEnv, который остается действительным, пока вы явно не уничтожите JVM. Местное / глобальное различие все еще применяется здесь? В чем смысл локальной ссылки на вновь созданный объект, поскольку JNIEnv постоянно находится в области видимости?

Ответы [ 3 ]

6 голосов
/ 02 июля 2012

Книга JNI немного краткая об этой ситуации, но вы можете понять это, если изучите ее достаточно долго.По сути, когда вы присоединяете собственный поток C к JVM, вы создаете локальный контекст, который может хранить некоторые локальные ссылки.

Эти локальные ссылки не будут никогда освобождаться, пока вы не освободите их вручную с помощьюDeleteLocalRef, или вы уничтожаете локальный контекст, вызывая DetachThread.Поскольку вы, вероятно, не выполняете много операций по присоединению и отсоединению к JVM, очень важно, чтобы вы вызывали DeleteLocalRef для каждой локальной ссылки, которую вы создаете.

Естественный следующий вопрос - почемувообще создавать глобальные ссылки, если локальные ссылки не получают GC до тех пор, пока JVM не будет отключена? "Ну, локальные ссылки не могут быть разделены между потоками.Поэтому вам все еще нужно создать глобальные ссылки для этого.

1 голос
/ 09 августа 2011

Предположительно, вызов DettachCurrentThread () также освобождает ссылки.К сожалению, спецификация JNI не дает четкого определения поведения ссылок для API вызова, и может оказаться, что фактическая семантика может зависеть от конкретной реализации JVM: S

1 голос
/ 13 октября 2010

Я думаю, что поток, создавший JVM, становится потоком Java, который, как и любой поток, созданный в Java или присоединенный через AttachCurrentThread (), имеет свой локальный фрейм стека. Таким образом, любой созданный вами объект становится локальной ссылкой в ​​этом стековом фрейме, срок действия которого истекает, когда вы уничтожаете JVM (вы не можете отсоединить основной поток) или вызываете DeleteLocalRef ().

...