Переполнение ReferenceTable (jni android), освобождение объектов массива

0

Я делаю игру для android, в которой я использую JNI. Через некоторое время я получаю эту ошибку:

12-25 22: 01: 23.304: W/dalvikvm (13096): переполнение ссылочной таблицы

(max = 1024) 12-25 22: 01: 23.304: W/dalvikvm (13096): последние 10 записей в

Таблица привязки массива JNI: 12-25 22: 01: 23.304:

W/dalvikvm (13096): 1014: 0x4052ffd8 cls = [I (28 bytes) 12-25

22: 01: 23.304: W/dalvikvm (13096): 1015: 0x4052fff8 cls = [I (28 bytes)

12-25 22: 01: 23,304: W/dalvikvm (13096): 1016: 0x40530018 cls = [I (28

байты) 12-25 22: 01: 23,304: W/dalvikvm (13096): 1017: 0x40530038 cls = [I

(28 bytes) 12-25 22: 01: 23.304: W/dalvikvm (13096): 1018: 0x40530058 cls = [I (28 bytes) 12-25 22: 01: 23.304: W/dalvikvm (13096): 1019:

0x40530078 cls = [I (28 bytes) 12-25 22: 01: 23.304: W/dalvikvm (13096):

1020: 0x40530098 cls = [I (28 bytes) 12-25 22: 01: 23.304:

W/dalvikvm (13096): 1021: 0x405300b8 cls = [I (28 bytes) 12-25

22: 01: 23.304: W/dalvikvm (13096): 1022: 0x405300d8 cls = [I (28 bytes)

12-25 22: 01: 23,304: W/dalvikvm (13096): 1023: 0x405300f8 cls = [I (28

байты) 12-25 22: 01: 23.304: W/dalvikvm (13096): JNI закрепленный массив

резюме справочной таблицы (1024 записи): 12-25 22: 01: 23.314:

W/dalvikvm (13096): 539 из [I 28B (113 уникальных) 12-25 22: 01: 23,314:

W/dalvikvm (13096): 140 из [I 36B (28 уникальных) 12-25 22: 01: 23.314:

W/dalvikvm (13096): 20 из [I 44B (4 уникальных) 12-25 22: 01: 23.314:

W/dalvikvm (13096): 325 из [I 52B (65 уникальных) 12-25 22: 01: 23,314:

W/dalvikvm (13096): память, сохраненная непосредственно отслеживаемыми ссылками, составляет 7728 байт

Я прочитал, что я должен освободить память (т.е. ReleaseIntArrayElements), но я не знаю, как это сделать в этом случае. У меня есть 2d массивы в java, я передаю их на нативную функцию и конвертирую локально в vector>.

jstring convert(JNIEnv *env, string ruch) {
  jstring result;
  char *writable = new char[ruch.size()+1];
  copy(ruch.begin(), ruch.end(), writable);
  writable[ruch.size()] = '\0';
  result = env->NewStringUTF(writable);
  delete[] writable;
  return result;
}

JNIEXPORT jstring JNICALL Java_pl_game_yapapersoccer_Ndk_move
  (JNIEnv *env, jclass obj, jint player, jint index, jint mode, jobjectArray matrix, jobjectArray matrixNeighbours, jobjectArray matrixWagi) {
    int matrix_size = env->GetArrayLength(matrix);
    vector<vector<int> > vMatrix(matrix_size);
    for (int i=0;i<matrix_size;i++) {
      vector<int> row(matrix_size);
      vMatrix[i] = row;

      jintArray oneDim= (jintArray)env->GetObjectArrayElement(matrix, i);
      env->GetIntArrayRegion( oneDim, 0, matrix_size, &vMatrix[i][0] );
    }

    vector<vector<int> > vMatrixNeighbours(matrix_size);
    for (int i=0;i<matrix_size;i++) {
      jintArray oneDim= (jintArray)env->GetObjectArrayElement(matrixNeighbours, i);
      jint *element=env->GetIntArrayElements(oneDim, 0);
      int rowSize = env->GetArrayLength(oneDim);
      vector<int> row(rowSize);
      vMatrixNeighbours[i] = row;
      env->GetIntArrayRegion( oneDim, 0, rowSize, &vMatrixNeighbours[i][0] );
    }

    vector<vector<int> > vMatrixWagi(matrix_size);
    for (int i=0;i<matrix_size;i++) {
      jintArray oneDim= (jintArray)env->GetObjectArrayElement(matrixWagi, i);
      jint *element=env->GetIntArrayElements(oneDim, 0);
      vector<int> row(2);
      vMatrixWagi[i] = row;
      env->GetIntArrayRegion( oneDim, 0, 2, &vMatrixWagi[i][0] );
    }

    // something something, ruch is c++ string, all legit
    return convert(env,ruch);

  }

Это работает для первых нескольких вызовов. Примером может служить пример для выпуска объектов. Если это не обязательно, я хотел бы сохранить 2d-массивы в java и векторах векторов в c++.

Теги:
jni

1 ответ

0
Лучший ответ

Поскольку я знаю, что если вы вызываете метод GetIntArrayElements, вы должны вызвать ReleaseIntArrayElements чтобы освободить ссылку. Вы можете просмотреть файл jni.h для поиска методов с именем Release **. Надеюсь, это может вам помочь.

  • 0
    Я признаю это, я потерпел неудачу. Ранее я использовал итерацию * element, но когда я перешел на intarrayregion, я забыл удалить строку jint * element = ..., которая больше не нужна.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню