Domanda

Ho capire come cumulo e garbage collector lavori: raccolta dei rifiuti avviene in generazioni, allocazione di memoria avviene sequenzialmente, durante garbage collection spazio libero / inutilizzato compattato spostando dati e formatura continua blocco, ecc

C'è qualche intestazioni per blocchi di memoria allocate sono presenti e quanto grande sono loro (ho sentito che è 8-16 byte per CLR .NET) e se byte, parola o quad-parola di allineamento presente? Sono interessato a tutte le informazioni per il JIT (Java) e CLR (.NET Framework o Mono) implementazione per x86 e x64 architetture dei processori.

È stato utile?

Soluzione

Credo che la dimensione di intestazione è di due parole - uno per il riferimento di tipo e uno per il blocco di sincronizzazione e altre bandiere. L'imbottitura è (credo) quanto basta per arrotondare la dimensione totale fino a tutta una serie di parole.

Per esempio, un tipo di riferimento con un semplice "int" in si 12 byte su x86, come dimostrato qui:

using System;

public class Foo
{
    int x;

    public Foo(int x)
    {
        this.x = x;
    }
}

public class Test
{
    static void Main(string[] args)
    {
        int length = int.Parse(args[0]);

        Foo x = new Foo(0);
        Foo[] array = new Foo[length];
        // Make sure that JITting the string constructor doesn't
        // change things
        long start = GC.GetTotalMemory(true);
        for (int i=0; i < length; i++)
        {
            array[i] = new Foo(i);
        }
        long end = GC.GetTotalMemory(true);

        GC.KeepAlive(array);
        GC.KeepAlive(x);

        decimal totalDecimal = end-start;
        Console.WriteLine(totalDecimal / length);
    }
}

Un punto interessante - per qualche motivo un'istanza di System.Object richiederà 12 byte (su 86) invece del 8 che avrei altrimenti potuto prevedere. E 'come se la dimensione minima è di 12 byte, ma si ottiene i primi quattro byte di dati reali gratuito:)

Non so il motivo per cui la dimensione segnalata non è esattamente un numero intero, btw - ho il sospetto che sia qualcosa a che fare con un po 'di memoria extra necessaria per per pagina nel mucchio gestito, o qualcosa del genere. A volte il risultato è un po 'più di 12, a volte un po' meno di 12 anni - che sembra dipendere dalla lunghezza data. (La versione precedente di questa risposta ha avuto un bug in, dove sarebbe analizzare il primo arg riga di comando, ma poi ignorarlo. Ho fissato questo.) In ogni caso, non credo che questo lieve imprecisione ha nulla a che fare con la dimensione di un singolo oggetto in memoria.

Altri suggerimenti

Una risposta completa al problema sarebbe in realtà piuttosto complicato: l'overhead associato con allocazione degli oggetti dipende non solo i dettagli di implementazione della particolare macchina virtuale, ma per esempio anche sulla generazione che l'oggetto sembra essere in (a altre parole, l'overhead associato a un oggetto particolare, possono cambiare durante la vita dell'oggetto).

Ci sono pochi semplici utility che possono essere utilizzate per stimare l'overhead per un oggetto particolare, ma nulla robusta (verificare per esempio http://java.sun.com/docs/books/performance/1st_edition/html/JPRAMFootprint.fm.html ).

In Java, c'è anche un'interfaccia che potrebbe dare la dimensione oggetto compreso in testa, vedi http://download-llnw.oracle.com/javase/6/docs/platform/jvmti/jvmti.html#GetObjectSize .

Non so su Java, ma per il CLR c'è un 1 parola nativa in testa per di riferimento tipo assegnati. Nei sistemi 32 bit sarà 4 byte e sistemi a 64 bit sarà 8 byte.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top