Manipolazione 256x256 bitmap schiantarsi JNI di android-NDK

voti
1

Forse sto cercando di fare qualcosa che non doveva.

Sto correndo un blocco di codice nell'emulatore. Sembra (più o meno) in questo modo: http://pastie.org/1291380

Questo è quello di costruire uno sfondo live wallpaper. Io passo in una bitmap, la tavolozza dei colori, e le dimensioni delle mattonelle array.The della mia bitmap è di 256 x 256. getRedPal / getGreenPal / getBluePal essenzialmente fa una chiamata a Color.red () / Color.green () / Color.blue () al fine di ottenere i componenti di colore RGB di un oggetto palette.

Le anse chug lungo; Ottengo tutta la strada fino al punto in cui il valore di j drawInC colpisce 32, prima che i crash dell'emulatore e ustioni:

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

Dopo di che ho un file di dump inviato a / dati / lapidi. Ecco la discarica (ma io sinceramente non trovo nulla in esso vale la pena qualsiasi valore, solo un mucchio di indirizzi di memoria): http://pastie.org/1291394

Ho aggiunto Android: vmSafeMode = true per il mio tag dopo aver letto altrove che che potrebbe risolvere un problema. Questo è il 2.2, utilizzando bitmap.h.

Personalmente sono dubbia che

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

chiamata; Mi feci che il codice da qualche parte rete, come mi è stato totalmente incapace di ottenere i valori dal mio array di byte arr.

Qualche idea?

EDIT Dopo la manipolazione miei iteratori ad anello (ho accorciato il numero di cicli), ora ottengo un errore informativo:

Troppo pieno 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)

Quel 509 di java.lang.Class Non sembra troppo giusto per me ... come posso ottimizzare il mio codice qui?

È pubblicato 12/11/2010 alle 15:43
fonte dall'utente
In altre lingue...                            


2 risposte

voti
2

Da quel messaggio di errore, sembra che alcuni po 'di codice nativo ha chiamato una funzione che restituisce un oggetto di classe, e lo ha fatto 509 volte. 507 di quelle chiamate restituito una classe particolare.

riferimenti locali JNI lasciare che il GC sapere che il codice nativo sta guardando un oggetto, e quindi che oggetto non possono essere raccolti, anche se non ci sono riferimenti ad esso altrove. Questi arbitri locali vengono rilasciati quando il codice nativo ritorna alla VM. Se il codice nativo fa un sacco di lavoro senza tornare, è possibile traboccare il tavolo rif locale.

Probabilmente solo bisogno di aggiungere un DeleteLocalRef da qualche parte. La mia ipotesi è che è necessario aggiungere uno alla fine del DrawTile, a causa della chiamata GetObjectClass. Meglio ancora, spostare quelli GetMethodID chiama ad una funzione di setup una tantum. (Lo fanno le ricerche di stringa per trovare il metodo, che li rende non particolarmente veloce.)

Per maggiori informazioni visita Tips JNI .

Risposto il 12/11/2010 a 21:14
fonte dall'utente

voti
0

Penso che questo potrebbe essere un problema di memoria. Non si rilascia le matrici?

se si ottiene con gli array

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

è necessario rilasciare la matrice sul c-side dopo ogni procedura o si riempirà la memoria fino ad ottenere oltre il limite (dimensioni limite dipende dalla versione Android e / o il produttore, ma è a mia conoscenza massimo 48MB per app)

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

vedere qui: http://www.iam.ubc.ca/guides/javatut99/native1.1/implementing/array.html

btw, questo metodo non copiare gli array da Java a un nuovo blocco di memoria in C, si lavora lì e alla fine la sua copiato torna a java (che la memoria potrebbe essere stato spostato in un'altra posizione fino a quel momento). per il miglioramento delle prestazioni si potrebbe guardare https://groups.google.com/forum/?fromgroups#!msg/android-ndk/phDP5zqiYY4/BFMw4zTme8IJ

Risposto il 20/04/2012 a 13:19
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more