Pregunta

He comprensión de cómo montón y recolector de basura funciona: la recogida de basura que pasa en generaciones, la asignación de memoria pasa secuencialmente, durante la recogida de basura espacio libre / no utilizado compactado mediante el desplazamiento de datos y la formación continúa bloque, etc.

¿Hay cualquiera de las cabeceras de trozos de memoria asignados están presentes y lo grande que son ellos (He escuchado que es 8-16 bytes para .NET CLR) y si el byte, palabra o palabra de alineación de cuatro presentes? Estoy interesado en cualquier información de JIT (Java) y CLR (.NET Framework o Mono) aplicación de arquitecturas de procesadores x86 y x64.

¿Fue útil?

Solución

Creo que el tamaño de la cabecera es de dos palabras - una para el tipo de referencia y otro para el bloque de sincronización y otras banderas. El relleno es (creo) lo suficiente como para redondear el tamaño total de hasta toda una serie de palabras.

Por ejemplo, un tipo de referencia con sólo un "int" en toma 12 bytes en x86, como se ha demostrado aquí:

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 interesante - por alguna razón una instancia de System.Object lleva 12 bytes (x86) en lugar de los 8 que de otro modo hubiera predicho. Es como si el tamaño mínimo es de 12 bytes, pero te dan los primeros cuatro bytes de datos reales libre:)

No sé por qué el tamaño reportado no es exactamente un entero, por cierto - Sospecho que es algo que ver con un poco de memoria extra que se requiere para por página en el montón administrado, o algo por el estilo. A veces, el resultado es un poco más del 12, a veces un poco menos de 12 años - que parece depender de la longitud dada. (La versión anterior de esta respuesta tenía un bug en donde sería analizar el primer argumento de línea de comandos, pero luego lo ignoran. Yo he fijado que.) De todos modos, no creo que esta ligera imprecisión tiene nada que ver con el tamaño de un objeto individual en la memoria.

Otros consejos

Una respuesta completa a la pregunta en realidad sería bastante complicado: la sobrecarga asociada con la asignación de objetos no sólo depende de los detalles de implementación de la máquina virtual en concreto, pero por ejemplo también en la generación que el objeto pasa a ser en (en otras palabras, la sobrecarga asociada a un objeto en particular puede cambiar durante el tiempo de vida del objeto).

Hay pocas utilidades simples que se pueden utilizar para estimar la sobrecarga para un objeto en particular, pero nada robusta (visita por ejemplo http://java.sun.com/docs/books/performance/1st_edition/html/JPRAMFootprint.fm.html ).

En Java, también hay una interfaz que podría darle el tamaño del objeto incluidos los gastos generales, véase http://download-llnw.oracle.com/javase/6/docs/platform/jvmti/jvmti.html#GetObjectSize .

Yo no sé acerca de Java, pero para el CLR no es una palabra nativa 1 sobrecarga por referencia tipo asignado. En los sistemas de 32 bits que será de 4 bytes y sistemas de 64 bits que será de 8 bytes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top