Andrjoid JNI просто для следующего возврата ошибки - PullRequest
0 голосов
/ 04 декабря 2011
    jstring Java_com_example_hellojni_HelloJni_buildString(JNIEnv *env, jobject sThis){
        for (int i=0; i < 100000; i++){
              char* c=(char*)env->NewStringUTF("xx");
        }

        return env->NewStringUTF("test");
    }

12-04 14: 46: 36.399: DEBUG / dalvikvm (8086): Попытка загрузить lib /data/data/com.example.hellojni/lib/libhello-jni.so 0x405143d8 12-04 14: 46: 36.399: DEBUG / dalvikvm (8086): добавлена ​​общая библиотека /data/data/com.example.hellojni/lib/libhello-jni.so 0x405143d8 12-04 14: 46: 36.431: WARN / dalvikvm (8086): переполнение ReferenceTable (макс. = 1024) 12-04 14: 46: 36.431: WARN / dalvikvm (8086): последние 10 записей в локальном JNI справочная таблица: 12-04 14: 46: 36.431: WARN / dalvikvm (8086): 1014: 0x4052b258 cls = Ljava / lang / String; (28 байт) 12-04 14: 46: 36.431: WARN / dalvikvm (8086): 1015: 0x4052b298 cls = Ljava / lang / String; (28 байт) 12-04 14: 46: 36.431: WARN / dalvikvm (8086): 1016: 0x4052b2d8 ЦБС = Ljava / языки / String; (28 байт) 12-04 14: 46: 36.431: WARN / dalvikvm (8086): 1017: 0x4052b318 cls = Ljava / lang / String; (28 байт) 12-04 14: 46: 36.431: WARN / dalvikvm (8086): 1018: 0x4052b358 ЦБС = Ljava / языки / String; (28 байт) 12-04 14: 46: 36.431: WARN / dalvikvm (8086): 1019: 0x4052b398 cls = Ljava / lang / String; (28 байт) 12-04 14: 46: 36.431: WARN / dalvikvm (8086): 1020: 0x4052b3d8 ЦБС = Ljava / языки / String; (28 байт) 12-04 14: 46: 36.431: WARN / dalvikvm (8086): 1021: 0x4052b418 cls = Ljava / lang / String; (28 байт) 12-04 14: 46: 36.431: WARN / dalvikvm (8086): 1022: 0x4052b458 ЦБС = Ljava / языки / String; (28 байт) 12-04 14: 46: 36.431: WARN / dalvikvm (8086): 1023: 0x4052b498 cls = Ljava / lang / String; (28 байт) 12-04 14: 46: 36.431: WARN / dalvikvm (8086): локальная ссылка JNI Сводная таблица (1024 записи): 12-04 14: 46: 36.431: WARN / dalvikvm (8086): 1 Лява / Ланг / Класс; 236B 12-04 14: 46: 36.431: WARN / dalvikvm (8086):
1 Лява / Ланг / Класс; 284B 12-04 14: 46: 36.431: WARN / dalvikvm (8086):
1 Лява / Ланг / Класс; 572B 12-04 14: 46: 36.431: WARN / dalvikvm (8086): 1020 из Лява / Ланг / Строка; 28B (1020 уникальных) 12-04 14: 46: 36.431: ПРЕДУПРЕЖДЕНИЕ / dalvikvm (8086): 1 из [Ljava / lang / String; 28B 12-04 14: 46: 36.431: WARN / dalvikvm (8086): память, удерживаемая непосредственно отслеживаемым refs составляет 29680 байт. 12-04 14: 46: 36.431: ОШИБКА / dalvikvm (8086): Ошибка добавление в локальную справочную таблицу JNI (имеет 1024 записи) INFO / dalvikvm (8086): «основной» prio = 5 тид = 1 RUNNABLE 12-04 14: 46: 36.431: INFO / dalvikvm (8086): | group = "main" sCount = 0 dsCount = 0 obj = 0x4001f1b8 self = 0xcee8 12-04 14: 46: 36.431: INFO / dalvikvm (8086):
| sysTid = 8086 nice = 0 sched = 0/0 cgrp = дескриптор по умолчанию = -1345006496 12-04 14: 46: 36.431: INFO / dalvikvm (8086): в com.example.hellojni.HelloJni.buildString (собственный метод) 12-04 14: 46: 36.431: INFO / dalvikvm (8086): в com.example.hellojni.HelloJni.onCreate (HelloJni.java:93)

странно. если мой следующий выглядит так:

for (int i=0; i < 100; i++){

тогда все окей.

Как я могу переписать этот код, чтобы запустить for next с большим числом?

Ответы [ 2 ]

0 голосов
/ 07 декабря 2011

Вы выделяете слишком много объектов Java за один вызов функции JNI. Dalvik сообщает, что вы заняли всю таблицу ссылок на объекты (в вашем случае 1024 объекта). Поэтому используйте массивы Java или другой способ хранения ваших данных.

Каждый раз, когда вы вызываете NewStringUTF, он копирует вашу строку в память, «принадлежащую» Java, и назначает объект для управления версией Java-строки (и памятью, используемой на стороне Java). Когда ваша ссылка выходит за рамки (в приведенном выше примере, когда возвращаются нативные функции), память, выделенная Java, будет освобождена, и ссылка будет удалена.

Каждый раз, когда локальная ссылка сохраняется на стороне Java (для отслеживания объекта и его памяти), она использует слот в таблице. Я не уверен, насколько большой будет эта таблица, но я уверен, что она относительно мала, может быть, 32 записи. В вашем случае это на самом деле 1024 больших (для конкретной реализации), но в любом случае есть предел, если вы превысите его, вы получите сбой, который вы испытываете.

С точки зрения того, как обойти эту проблему, очевидным правилом является использование меньшего количества локальных ссылок. Из вашего фрагмента кода неясно, что должен делать цикл for, но приведение к (char *) указывает на фундаментальное отсутствие понимания того, что на самом деле делает код. Если вы сохранили его как jstring, у вас есть возможность впоследствии вызвать env-> DeleteLocalRef (...), чтобы удалить ссылку. В любом случае, просьба предоставить дополнительную информацию, если вы пытаетесь достичь чего-то конкретного.

0 голосов
/ 04 декабря 2011

если вы вызываете этот метод из потока пользовательского интерфейса, то он будет приостановлен на 1,4 минуты, и Android закроет любую программу, которая не отвечает на 5 секунд. Это поможет вам использовать AsyncTask или выполнить этот вызов в другом потоке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...