Управление сбоями растровых изображений 256x256 в JNI для android-ndk - PullRequest
1 голос
/ 12 ноября 2010

Возможно, я пытаюсь сделать что-то, чего не должен делать.

Я запускаю блок кода в эмуляторе.Это выглядит (более или менее) так: http://pastie.org/1291380

Это для создания живого фона обоев.Я передаю растровое изображение, цветовую палитру и массив плиток. Размер моего растрового изображения составляет 256 x 256. getRedPal / getGreenPal / getBluePal по существу выполняет вызов Color.red () / Color.green () / Color.blue ()чтобы получить компоненты цвета rgb объекта палитры.

Петли запыхиваются;Я дошел до того, что значение j drawInC достигло 32, до того как эмулятор вышел из строя и сгорел:

11-11 15: 34: 44.032: INFO / distort_bmp (598): DrawInC: i:0 j: 32

11-11 15: 34: 44.032: INFO / distort_bmp (598): DrawTiles: i: 0 j: 0

11-11 15: 34: 44.032: INFO/ distort_bmp (598): DrawTiles: i: 0 j: 1

11-11 15: 34: 44.032: INFO / distort_bmp (598): DrawTiles: i: 0 j: 2

11-11 15: 34: 44.032: INFO / distort_bmp (598): DrawTiles: i: 0 j: 3

11-11 15: 34: 44.032: INFO / distort_bmp (598): DrawTiles: i:0 j: 4

После чего я получаю файл дампа, отправленный в / data / tombstones.Вот дамп (но я искренне не нахожу в нем ничего ценного, просто набор адресов памяти): http://pastie.org/1291394

Я добавил android: vmSafeMode = "true" в мойпосле прочтения в другом месте, что это может решить проблему.Это на 2.2, используя bitmap.h.

Лично я сомневаюсь в этом

jbyte* buffer = 
(*env)->GetByteArrayElements(env, arr, &isCopy)

призыве;Я где-то взял этот код из сети, так как не смог получить значения из моего байтового массива "arr".

Есть идеи?

РЕДАКТИРОВАТЬ После манипуляции с итераторами циклов (я сократил количество циклов) я теперь получаю информативную ошибку:

"Переполнение ReferenceTable (max = 512) "

JNI local reference table summary (512 entries):
  509 of Ljava/lang/Class; 164B (3 unique)
2 of Ljava/lang/String; 28B (2 unique)
   1 of [Ljava/lang/String; 28B
Memory held directly by tracked refs is 576 bytes
Failed adding to JNI local ref table (has 512 entries)

То, что" 509 из java.lang.class "не выглядит слишком правильным для меня ... как я могу оптимизировать свой код здесь?

Ответы [ 2 ]

2 голосов
/ 13 ноября 2010

Из этого сообщения об ошибке видно, что некоторый бит нативного кода вызвал функцию, которая возвращает объект Class, и сделал это 509 раз.507 из этих вызовов вернули один конкретный класс.

Локальные ссылки JNI позволяют GC знать, что нативный код смотрит на объект, и поэтому этот объект не может быть собран, даже если в другом месте нет ссылок на него.Эти локальные ссылки освобождаются, когда собственный код возвращается на виртуальную машину.Если нативный код выполняет большую часть работы без возврата, возможно переполнить локальную таблицу ссылок.

Возможно, вам просто нужно где-то добавить DeleteLocalRef.Я думаю, вам нужно добавить один в конце DrawTile из-за вызова GetObjectClass.Еще лучше, переместите эти вызовы GetMethodID в функцию однократной настройки.(Они выполняют поиск строк, чтобы найти метод, что делает их не особенно быстрыми.)

Для получения дополнительной информации см. JNI Tips .

0 голосов
/ 20 апреля 2012

Я думаю, это может быть проблема с памятью.вы освобождаете массивы?

если вы получаете массивы с

(*env)->GetByteArrayElements(env, arr, &isCopy)

, вы должны освобождать массив на стороне c после каждой процедуры, или вы будете заполнять свою память, пока не закончитепредел (размер ограничения зависит от версии Android и / или производителя, но, насколько мне известно, не более 48 МБ на приложение)

(*env)->ReleaseByteArrayElements(env, arr, &isCopy, 0);

см. здесь: http://www.iam.ubc.ca/guides/javatut99/native1.1/implementing/array.html

Кстати, этот метод копируетмассивы из Java в новый блок памяти в C, вы работаете там, и в конце его копируется обратно в Java (какая память могла быть перемещена в другое место до тех пор).для улучшения производительности вы можете посмотреть на https://groups.google.com/forum/?fromgroups#!msg/android-ndk/phDP5zqiYY4/BFMw4zTme8IJ

...