2012-09-03 17 views
9

Devo memorizzare milioni di doppie coppie X/Y come riferimento nel mio programma Java. Mi piacerebbe mantenere il consumo di memoria il più basso possibile e il numero di riferimenti a oggetti. Così, dopo qualche riflessione ho deciso tenendo i due punti in un piccolo doppio array potrebbe essere una buona idea, è di impostazione appare in questo modo:Dimensioni della memoria Java della classe vs della memoria?

double[] node = new double[2]; 
node[0] = x; 
node[1] = y; 

Ho calcolato utilizzando la matrice impedirebbe il legame tra la classe e il mio X e variabili Y utilizzate in una classe, come segue:

class Node { 
    public double x, y; 
} 

Tuttavia dopo aver letto sul modo in cui i campi pubblici in classi sono memorizzate, mi sono reso conto che i campi non possono effettivamente essere strutturati come puntatore come le strutture, forse la JVM è semplicemente memorizzando questi valori nella memoria contigua e sa come trovarli senza un indirizzo, rendendo così la rappresentazione di classe del mio punto più piccolo dell'array.

Quindi la domanda è, che ha un minore ingombro di memoria? E perché?

Sono particolarmente interessato al fatto che i campi delle classi utilizzino o meno un puntatore e quindi abbiano un overhead a 32 bit oppure no.

risposta

5

Quest'ultimo ha l'ingombro minore.

I tipi primitivi sono memorizzati in linea nella classe contenente. Quindi il tuo Node richiede un'intestazione di un oggetto e due slot a 64 bit. La matrice specificata utilizza un'intestazione di matrice (> = un'intestazione di oggetto) plust due slot a 64 bit.

Se si assegnano 100 variabili in questo modo, non importa tanto, poiché sono solo le dimensioni dell'intestazione che sono diverse.

Avvertenza: tutto ciò è alquanto speculativo in quanto non è stata specificata la JVM: alcuni di questi dettagli potrebbero variare da JVM.

+0

Attualmente in esecuzione Java 1.7 SE in x64 su Mac OS X. Ora sto assumendo che un gigantesco array 2D eliminerebbe del tutto il riferimento all'oggetto necessario per ogni nodo, quindi sarebbe di gran lunga il modo più conservativo di memoria per andare? –

+0

se per 2D si intende doppio [2] [n] o doppio [n] [2], che porterà anche a riferimenti di oggetti. dato che gli array in java sono veramente array di array in questo caso –

+0

(Sei * modo * di sovra-ottimizzare questo, ma ...) Il minimo ingombro di memoria sarebbe un array 1-D in cui si calcolano gli indici in modo esplicito. Gli array 2D in Java sono solo una serie di puntatori agli array 1D. –

0

Non penso che il tuo problema più grande stia memorizzando i dati, penso che lo recupereremo, indicizzeremo e manipoleremo.

Tuttavia, un array, fondamentalmente, è la strada da percorrere. Se vuoi risparmiare sui puntatori, usa un array monodimensionale. (Qualcuno l'ha già detto).

0

Innanzitutto, è necessario specificare che l'utilizzo dello spazio effettivo dipende dalla JVM che si sta utilizzando. È strettamente specifico per l'implementazione. Quanto segue è per una tipica JVM mainstream.

Quindi la domanda è, che ha un minore ingombro di memoria? E perché?

La seconda versione è più piccola. Un array ha il sovraccarico del campo a 32 bit nell'intestazione dell'oggetto che contiene la lunghezza dell'array. Nel caso di un oggetto non matrice, la dimensione è implicita nella classe e non è necessario rappresentarla separatamente.

Ma si noti che questo è un overhead fisso per oggetto array. Più grande è la matrice, meno importante è il sovraccarico in termini pratici. E il rovescio della medaglia di usare una classe piuttosto che l'array è che l'indicizzazione non funzionerà e il tuo codice potrebbe essere più complicato (e più lento) di conseguenza.

Un array Java 2D è in realtà e array di array 1D (eccetera), quindi è possibile applicare la stessa analisi agli array con dimensionalità più elevata.Maggiore è la dimensione di un array in qualsiasi dimensione, minore è l'impatto del sovraccarico. Il sovraccarico in un array 2x10 sarà inferiore rispetto a un array 10x2. (Si pensi attraverso ... 1 array di lunghezza 2 + 2 di lunghezza 10 contro 1 array di lunghezza 10 + 10 di lunghezza 2. L'overhead è proporzionale al numero di array.)

I' Mi interessa in particolare se i campi delle classi utilizzano o meno un puntatore, e quindi hanno un overhead a 32 bit, oppure no.

(in realtà si sta parlando di campi esempio, non campi di classe. Questi campi non sono static ...)

campi il cui tipo è un tipo primitivo sono memorizzati direttamente nel nodo mucchio dell'oggetto senza qualsiasi riferimento Non c'è nessun overhead del puntatore in questo caso.

Tuttavia, se i tipi di campo erano tipi involucro (per esempio Double anziché double) allora ci potrebbe essere il sovraccarico di riferimento e le spese generali dell'intestazione oggetto per l'oggetto Double.

+0

Questo chiarisce molto bene la mia domanda iniziale, grazie! –