2010-10-27 12 views
8

¿Cuál es la forma correcta de medir cuánta memoria del montón debe usarse para crear un nuevo objeto de un cierto tipo (hablemos de enteros para que sea sencillo)?¿Cuánta memoria se asigna para un objeto Integer en Java? ¿Cómo averiguar este valor para cualquier objeto personalizado?

¿Se puede calcular este valor sin experimentar? ¿Cuáles son las reglas en ese caso? ¿Están estas reglas estrictamente especificadas en alguna parte o pueden variar de jvm a jvm?

+0

No varían por máquina pero no hay operador sizeof en java si esto es lo que está preguntando – Cratylus

Respuesta

14

Podría variar de JVM a JVM.

Es posible que como this blog post de un ingeniero de Oracle:

En el caso de un número entero de Java en un Hotspot JVM de 32 bits, la carga útil de 32 bits (un campo Integer.value) se acompaña de una 96 bits adicionales, una marca, un klass y una palabra de relleno de alineación, para un total de 128 bits. Además, si hay (digamos) seis referencias a este entero en el mundo (hilos más montón), esas referencias también ocupan 192 bits, para un total de 320 bits. En una máquina de 64 bits, todo es dos veces más grande, al menos en la actualidad: 256 bits en el objeto (que ahora incluye 96 bits de relleno) y 384 bits en otros lugares. Por el contrario, seis copias de un entero primitiva sin embalaje ocupan 192 bits

0

Eso no es fácil de hacer en Java: sizeof no existe y soluciones alternativas, tales como la serialización de los objetos en un flujo de bytes y mirando a la corriente del resultante longitud, no funcionan en todos los casos (por ejemplo, cadenas).

Sin embargo, vea this quite complicated implementation usando gráficos de objetos.

+1

probablemente ha vinculado este hilo en su respuesta por error :) – Roman

+0

@Roman, whoops, error editado :) –

1

Es posible que desee ver la instrumentación de Java para descubrirlo. Here es un ejemplo de lo mismo.

En su caso, como creo que desea encontrar el tamaño de los objetos de su aplicación, hará que el objeto Instrumentation esté disponible globalmente (static) para que pueda acceder a él desde su aplicación.

código copiado desde el enlace:

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); 
    } 
} 

Sin embargo, creo que usted será capaz de encontrar el tamaño de sólo objetos (no tipos primitivos, también que no necesite para encontrarlos a medida que ya les saber :-))

Nota que el método getObjectSize() no incluye la memoria utilizada por otros objetos referenciados por el objeto pasado en. por ejemplo, si objeto a tiene una referencia a Ob ject B, luego la memoria informada del objeto A el uso incluirá solo los bytes necesarios para la referencia al Objeto B (generalmente 4 bytes), no el objeto real.

Para obtener un recuento "profunda" del uso de la memoria de un objeto (es decir, que incluye "objetos parciales" o objetos mencionados por el objeto "principal"), entonces usted puede utilizar el agente Classmexer disponible para descarga beta desde el sitio this.

Cuestiones relacionadas