Создание объектов JNI и управление памятью - PullRequest
13 голосов
/ 21 февраля 2012

У меня есть следующий метод JNI, который изначально создает коллекцию объектов Java, а затем возвращает их в Java:

JNIEXPORT jobject JNICALL Java_com_test_myClass_myMethod(JNIEnv * env, jclass klass) {
    jclass arrayClass = env->FindClass("java/util/ArrayList");
    jmethodID initMethod = env->GetMethodID(arrayClass, "<init>", "()V");
    jmethodID addMethod = env->GetMethodID(arrayClass, "add", "(Ljava/lang/Object;)Z");
    jobject myArray = env->NewObject(arrayClass, initMethod);

    env->CallBooleanMethod(myArray, addMethod, env->NewStringUTF("Hello"));
    env->CallBooleanMethod(myArray, addMethod, env->NewStringUTF("World"));

    return myArray;
}

Нужно ли освобождать объекты, созданные в собственном коде, или GC делает это автоматически? Если я это сделаю, то как мне это сделать, поскольку мне нужно вернуть его на Java?

1 Ответ

13 голосов
/ 21 февраля 2012

Вам не нужно освобождать объекты Java, созданные в собственном коде.На самом деле, вы не можете.Сборщик мусора может освободить объект, если больше не осталось ссылок.

Иногда в нативном коде полезно освобождать ссылки на объекты Java.Это может снизить требования к памяти, когда собственный код содержит, но больше не нуждается, ссылки на большие объекты или большое количество ссылок.

От: «Глобальные и локальные ссылки» в спецификации JNI .

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

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

Была предоставлена ​​дополнительная информация. См. "Освобождение ссылок" в Руководстве программиста JNI.

...