2012-10-25 15 views
8

Le macchine virtuali Java possono utilizzare la larghezza int per i campi short (ciò dipende dalla loro implementazione interna). Solo gli array (short[]) sono un'eccezione, dove è sempre garantito che occupino meno spazio di uno int[] internamente). Che mi dici di Dalvik?Memoria richiesta per campi "corti" in Dalvik?

E.g. Ho una classe che contiene 50 campi di tipo short. A volte nella mia applicazione esistono 10000 di queste classi. Ciò significa che i campi short devono utilizzare 1 MB di memoria, ma se Dalvik utilizza 4 byte per i valori di short internamente, quindi l'utilizzo di memoria da 2 MB.

Quanta memoria dovrei aspettarmi dal Dalvik? (Questo si riferisce al suo uso di memoria interna, e sono consapevole del fatto che potrebbe non essere riflesso dall'utilizzo della memoria di sistema, ad esempio perché Dalvik ha già riservato una maggiore quantità di memoria dal sistema.)

+1

All'utente che ha preparato una modifica (di formattazione) al mio post: grazie. Sfortunatamente, il sistema non mi ha permesso di accettarlo, ha detto che "la modifica era già stata rifiutata". Quindi, per quanto ho potuto ricordare, ho provato ad applicare le tue modifiche da solo. –

+0

"Le macchine virtuali Java sono conosciute per l'utilizzo della larghezza int-sized anche per i campi brevi" è possibile eseguire il backup di questa istruzione con qualsiasi riferimento? – kosa

+0

Ero un po 'impreciso lì, quindi l'ho modificato. Ecco alcuni argomenti relativi allo stackoverflow: http://stackoverflow.com/questions/8855754/android-does-short-take-really-2-bytes http://stackoverflow.com/questions/1904857/which-is-better- to-use-short-or-int –

risposta

4

In dalvik, i campi doppio e lungo sono 8 byte, tutto il resto (incluso breve) è 4 byte.

D'altro canto, gli array corti richiedono 2 byte per elemento (oltre allo spazio iniziale per l'array + la contabilità degli oggetti).

Arrays

Il codice operativo new-array chiama dvmAllocArrayByClass (linea 71) per allocare spazio. Questo quindi chiama dvmAllocPrimitiveArray (riga 113).Nello switch dvmAllocPrimitiveArray, il caso 'S' viene utilizzato per un array breve. Potete vederlo chiama allocArray (riga 38) con larghezza = 2.

Da allocArray, esso esegue le seguenti operazioni di calcolo per calcolare la dimensione dell'array:

size_t elementShift = sizeof(size_t) * CHAR_BIT - 1 - CLZ(elemWidth); 
size_t elementSize = length << elementShift; 
size_t headerSize = OFFSETOF_MEMBER(ArrayObject, contents); 
size_t totalSize = elementSize + headerSize; 

Per breve, un sistema a 32 bit, questo calcolo sarebbe:

size_t elementShift = (4 * 8) - 1 - 30; //== 1; 
size_t elementSize = length << 1; //i.e. length * 2 
size_t headerSize = <some constant value>; 
size_t totalSize = length*2 + <some constant value>; 

Gli array corti richiedono 2 byte per elemento.

Fields

Il codice operativo new-instance chiama dvmAllocObject (linea 181) per allocare spazio per il nuovo oggetto. La dimensione assegnata si basa sul campo objectSize di ClassObject. objectSize è impostato su computeFieldOffsets (riga 3543). Se trovi tutte le istanze di dove fieldOffset viene incrementato in questa funzione, noterai che è sempre incrementato in step di 4 byte.

I campi brevi richiedono 4 byte.

+0

Questo è esattamente il tipo di risposta analitica che stavo cercando. Grazie! –

2

(Would essere un commento, ma è troppo lungo.)

È piuttosto normale che i campi a 4 byte vengano utilizzati per "locali" brevi, poiché la JVM è concettualmente una macchina con registri a 4 byte e con tutti l'altra spazzatura in una cornice dello stack non fa molta differenza.

Ad esempio, è probabile che i campi dipenderanno dal compromesso tra risparmio di storage e cicli di espansione e allineamento: l'ampliamento spesso costa un ciclo minore e anche su architetture che sono presumibilmente "agnostiche" per quanto riguarda l'allineamento dei confini di solito c'è una penalità per l'accesso fuori confine, quindi i campi di "imballaggio" senza prima riorganizzarli per mantenere i confini parola/doppia parola possono costare prestazioni.

Quindi, se la JVM sceglie di "impacchettare", è generalmente necessario riordinare i campi. Le JVM Naive eviteranno di riorganizzare poiché questo semplifica molti aspetti della JVM, ma (come un esempio) su AS/400 abbiamo riscontrato che il riordino e il riempimento aggressivo dei campi istanza sono stati ottenuti nell'ordine del 30% di miglioramento delle prestazioni per le app affamate di storage.

Non ho mai guardato l'interno di Dalvik. Le JVM standard derivate da Sun hanno storicamente (non guardato nulla di recente) dipendenti dal layout/dall'ordine delle cose nel file .class, e quindi non sono "naturalmente" suscettibili di riordinare. Ma Dalvik costituisce nuovamente il file .class e quindi è in una posizione migliore per effettuare il riordino dei campi di istanza.

Si noti che per verificare l'ipotesi che Dalvik impacchetta i campi short si dovrà creare una classe con decine di campi di istanza back-to-back e quindi determinare quale sia la dimensione dell'oggetto risultante. Inoltre (supponendo che l'imballaggio sia visto nel primo caso), creare una classe con short e int (o forse long) campi intercalati, per vedere se Dalvik li riordina per ottenere l'imballaggio.

Problemi correlati