2010-10-27 5 views
8

Qual è il modo corretto per misurare quanta memoria dall'heap deve essere utilizzata per creare un nuovo oggetto di un certo tipo (parliamo di numeri interi per mantenerlo semplice)?Quanta memoria è allocata per un oggetto intero in Java? Come scoprire questo valore per qualsiasi oggetto personalizzato?

Questo valore può essere calcolato senza esperimento? Quali sono le regole in quel caso? Queste regole sono rigorosamente specificate da qualche parte o possono variare da jvm a jvm?

+0

Non variano per macchina ma non c'è operatore sizeof in java se questo è quello che stai chiedendo – Cratylus

risposta

14

Potrebbe variare da JVM a JVM.

È possibile, come this blog post da un ingegnere di Oracle:

Nel caso di un numero intero Java su un 32 bit Hotspot JVM, il 32 bit payload (un campo Integer.value) è accompagnata da un 96 bit aggiuntivi, un segno, un klass e una parola di riempimento di allineamento, per un totale di 128 bit. Inoltre, se ci sono (diciamo) sei riferimenti a questo intero nel mondo (thread più heap), questi riferimenti occupano anche 192 bit, per un totale di 320 bit. Su una macchina a 64-bit, tutto è due volte più grande, almeno attualmente: 256 bit nell'oggetto (che ora include 96 bit di padding) e 384 bit altrove. Al contrario, sei copie di un intero primitivo unboxed occupano 192 bit

0

Questo non è facile da fare in Java: sizeof non esiste e soluzioni alternative, come serializzare gli oggetti in un flusso di byte e guardando il risultante flusso di lunghezza, non funzionano in tutti i casi (es. archi).

Tuttavia, vedere this quite complicated implementation utilizzando i grafici degli oggetti.

+1

hai probabilmente collegato questa discussione nella tua risposta per errore :) – Roman

+0

@Roman, whoops, errore modificato :) –

1

Si potrebbe voler guardare la strumentazione Java per scoprirlo. Here è un esempio dello stesso.

Nel tuo caso, poiché ritengo che desideri trovare la dimensione degli oggetti dall'applicazione, renderà l'oggetto Instrumentation disponibile a livello globale (static) in modo che sia possibile accedervi dall'applicazione.

codice copiato dal link:

public class MyAgent { 
    private static volatile Instrumentation globalInstr; 
    public static void premain(String args, Instrumentation inst) { 
    globalInstr = inst; 
    } 
    public static long getObjectSize(Object obj) { 
    if (globalInstr == null) 
     throw new IllegalStateException("Agent not initted"); 
    return globalInstr.getObjectSize(obj); 
    } 
} 

Tuttavia, credo che sarà in grado di trovare la dimensione di soli oggetti (non tipi primitivi, anche non necessari per trovarli fuori, come si già li so :-))

noti che il metodo getObjectSize() non include la memoria utilizzata da altri oggetti a cui fa riferimento l'oggetto passato. ad esempio, se oggetto a ha un riferimento a Ob ject B, quindi l'utilizzo della memoria della memoria segnalata dall'oggetto A includerà solo i byte necessari per il riferimento all'oggetto B (in genere 4 byte), non l'oggetto effettivo.

Per ottenere un conteggio "profonda" del l'utilizzo della memoria di un oggetto (cioè che include "oggetti secondari" o gli oggetti a cui si riferisce l'oggetto "principale"), quindi è possibile utilizzare l'agente Classmexer disponibile per il beta scaricare dal sito this.

Problemi correlati