Cómo determinar el tamaño de un objeto en Java

20 minutos de lectura

Avatar de usuario de Jay R.
jay r

Tengo una aplicación que lee un archivo CSV con montones de filas de datos. Le doy al usuario un resumen de la cantidad de filas en función de los tipos de datos, pero quiero asegurarme de no leer demasiadas filas de datos y causar OutOfMemoryErrors. Cada fila se traduce en un objeto. ¿Hay alguna manera de averiguar el tamaño de ese objeto mediante programación? ¿Hay alguna referencia que defina qué tan grandes son los tipos primitivos y las referencias a objetos para un VM?

En este momento, tengo un código que dice leer hasta 32.000 filaspero también me gustaría tener un código que diga leer tantas filas como sea posible hasta que haya usado 32MB de la memoria

  • Agregué mi Agente con configuraciones mvn y expliqué cómo aquí: stackoverflow.com/a/36102269/711855

    – Juanmf

    19 de marzo de 2016 a las 13:28

Avatar de usuario de Stefan Karlsson
Stefan Karlsson

Puedes usar el java.lang.instrument paquete.

Compile y ponga esta clase en un JAR:

import java.lang.instrument.Instrumentation;

public class ObjectSizeFetcher {
    private static Instrumentation instrumentation;

    public static void premain(String args, Instrumentation inst) {
        instrumentation = inst;
    }

    public static long getObjectSize(Object o) {
        return instrumentation.getObjectSize(o);
    }
}

Agregue lo siguiente a su MANIFEST.MF:

Premain-Class: ObjectSizeFetcher

Utilizar el getObjectSize() método:

public class C {
    private int x;
    private int y;

    public static void main(String [] args) {
        System.out.println(ObjectSizeFetcher.getObjectSize(new C()));
    }
}

Invocar con:

java -javaagent:ObjectSizeFetcherAgent.jar C

  • @Stefan ¡Buena pista! ¿Puedes decir cuál será el tamaño de byte[0], byte[1], byte[5], int[0], int[1], int[2] usando el enfoque que describiste? Sería bueno si los resultados incluyen gastos generales para la longitud de la matriz y la alineación de la memoria.

    – dma_k

    8 de marzo de 2010 a las 11:28

  • Intenté esto y obtuve resultados extraños e inútiles. Las cuerdas siempre fueron 32, independientemente del tamaño. Pensé que tal vez era el tamaño del puntero, pero para otra clase inmutable que creé, obtuve 24. Funciona bien para primitivas, pero realmente no necesitas un programa que te diga qué tan grande es un carácter.

    – Brel

    16 de septiembre de 2011 a las 12:39

  • @Brel, esta solución es solo una “aproximación de la cantidad de almacenamiento consumido por el objeto especificado”, como se especifica en la documentación. También supongo que los autores decidieron establecer el tamaño de una cadena en 32 bytes (¿solo el puntero?) debido al grupo de cadenas de Java, lo que dificulta decir si una instancia de cadena se comparte (almacenada en el grupo) o local y exclusivo de una clase.

    – VG

    17 de julio de 2013 a las 8:33


  • ¿Cómo puedo usar ObjectSizeFetcher, si no exporto jar? Tengo un proyecto java de prueba en eclipse.

    – Yura Shinkarev

    5 de agosto de 2013 a las 18:40

  • @brel La razón por la que una cadena tiene solo 32 bytes, independientemente de la longitud real, se debe a que la parte de longitud variable de una cadena se almacena en un carácter[], que es su propio objeto. Para obtener el tamaño real de un objeto, debe agregar el tamaño de sí mismo y el tamaño de cada objeto al que hace referencia.

    – tobrown52

    31 de mayo de 2018 a las 16:05

Deberías usar alegríauna herramienta desarrollada como parte del proyecto OpenJDK.

JOL (Java Object Layout) es la pequeña caja de herramientas para analizar esquemas de diseño de objetos en JVM. Estas herramientas utilizan en gran medida Unsafe, JVMTI y Serviceability Agent (SA) para decodificar el diseño, el espacio y las referencias reales del objeto. Esto hace que JOL sea mucho más preciso que otras herramientas que se basan en volcados de almacenamiento dinámico, suposiciones de especificación, etc.

Para obtener los tamaños de primitivas, referencias y elementos de matriz, use VMSupport.vmDetails(). En Oracle JDK 1.8.0_40 que se ejecuta en Windows de 64 bits (utilizado para todos los ejemplos siguientes), este método devuelve

Running 64-bit HotSpot VM.
Using compressed oop with 0-bit shift.
Using compressed klass with 3-bit shift.
Objects are 8 bytes aligned.
Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

Puede obtener el tamaño superficial de una instancia de objeto usando ClassLayout.parseClass(Foo.class).toPrintable() (opcionalmente pasando una instancia a toPrintable). Este es solo el espacio consumido por una sola instancia de esa clase; no incluye ningún otro objeto referenciado por esa clase. Él hace incluya la sobrecarga de VM para el encabezado del objeto, la alineación del campo y el relleno. Para java.util.regex.Pattern:

java.util.regex.Pattern object internals:
 OFFSET  SIZE        TYPE DESCRIPTION                    VALUE
      0     4             (object header)                01 00 00 00 (0000 0001 0000 0000 0000 0000 0000 0000)
      4     4             (object header)                00 00 00 00 (0000 0000 0000 0000 0000 0000 0000 0000)
      8     4             (object header)                cb cf 00 20 (1100 1011 1100 1111 0000 0000 0010 0000)
     12     4         int Pattern.flags                  0
     16     4         int Pattern.capturingGroupCount    1
     20     4         int Pattern.localCount             0
     24     4         int Pattern.cursor                 48
     28     4         int Pattern.patternLength          0
     32     1     boolean Pattern.compiled               true
     33     1     boolean Pattern.hasSupplementary       false
     34     2             (alignment/padding gap)        N/A
     36     4      String Pattern.pattern                (object)
     40     4      String Pattern.normalizedPattern      (object)
     44     4        Node Pattern.root                   (object)
     48     4        Node Pattern.matchRoot              (object)
     52     4       int[] Pattern.buffer                 null
     56     4         Map Pattern.namedGroups            null
     60     4 GroupHead[] Pattern.groupNodes             null
     64     4       int[] Pattern.temp                   null
     68     4             (loss due to the next object alignment)
Instance size: 72 bytes (reported by Instrumentation API)
Space losses: 2 bytes internal + 4 bytes external = 6 bytes total

Puede obtener una vista resumida del tamaño profundo de una instancia de objeto usando GraphLayout.parseInstance(obj).toFootprint(). Por supuesto, algunos objetos en la huella pueden compartirse (también referenciados desde otros objetos), por lo que es una aproximación excesiva del espacio que podría recuperarse cuando ese objeto se recolecta como basura. por el resultado de Pattern.compile("^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$") (tomado de esta respuesta), jol informa una huella total de 1840 bytes, de los cuales solo 72 son la instancia de Pattern en sí.

java.util.regex.Pattern instance footprint:
     COUNT       AVG       SUM   DESCRIPTION
         1       112       112   [C
         3       272       816   [Z
         1        24        24   java.lang.String
         1        72        72   java.util.regex.Pattern
         9        24       216   java.util.regex.Pattern$1
        13        24       312   java.util.regex.Pattern$5
         1        16        16   java.util.regex.Pattern$Begin
         3        24        72   java.util.regex.Pattern$BitClass
         3        32        96   java.util.regex.Pattern$Curly
         1        24        24   java.util.regex.Pattern$Dollar
         1        16        16   java.util.regex.Pattern$LastNode
         1        16        16   java.util.regex.Pattern$Node
         2        24        48   java.util.regex.Pattern$Single
        40                1840   (total)

Si en cambio usas GraphLayout.parseInstance(obj).toPrintable(), jol le dirá la dirección, el tamaño, el tipo, el valor y la ruta de las desreferencias de campo a cada objeto al que se hace referencia, aunque eso suele ser demasiado detallado para ser útil. Para el ejemplo de patrón en curso, puede obtener lo siguiente. (Es probable que las direcciones cambien entre ejecuciones).

java.util.regex.Pattern object externals:
          ADDRESS       SIZE TYPE                             PATH                           VALUE
         d5e5f290         16 java.util.regex.Pattern$Node     .root.next.atom.next           (object)
         d5e5f2a0        120 (something else)                 (somewhere else)               (something else)
         d5e5f318         16 java.util.regex.Pattern$LastNode .root.next.next.next.next.next.next.next (object)
         d5e5f328      21664 (something else)                 (somewhere else)               (something else)
         d5e647c8         24 java.lang.String                 .pattern                       (object)
         d5e647e0        112 [C                               .pattern.value                 [^, [, a, -, z, A, -, Z, 0, -, 9, _, ., +, -, ], +, @, [, a, -, z, A, -, Z, 0, -, 9, -, ], +, \, ., [, a, -, z, A, -, Z, 0, -, 9, -, ., ], +, $]
         d5e64850        448 (something else)                 (somewhere else)               (something else)
         d5e64a10         72 java.util.regex.Pattern                                         (object)
         d5e64a58        416 (something else)                 (somewhere else)               (something else)
         d5e64bf8         16 java.util.regex.Pattern$Begin    .root                          (object)
         d5e64c08         24 java.util.regex.Pattern$BitClass .root.next.atom.val$rhs        (object)
         d5e64c20        272 [Z                               .root.next.atom.val$rhs.bits   [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
         d5e64d30         24 java.util.regex.Pattern$1        .root.next.atom.val$lhs.val$lhs.val$lhs.val$lhs.val$lhs.val$lhs (object)
         d5e64d48         24 java.util.regex.Pattern$1        .root.next.atom.val$lhs.val$lhs.val$lhs.val$lhs.val$lhs.val$rhs (object)
         d5e64d60         24 java.util.regex.Pattern$5        .root.next.atom.val$lhs.val$lhs.val$lhs.val$lhs.val$lhs (object)
         d5e64d78         24 java.util.regex.Pattern$1        .root.next.atom.val$lhs.val$lhs.val$lhs.val$lhs.val$rhs (object)
         d5e64d90         24 java.util.regex.Pattern$5        .root.next.atom.val$lhs.val$lhs.val$lhs.val$lhs (object)
         d5e64da8         24 java.util.regex.Pattern$5        .root.next.atom.val$lhs.val$lhs.val$lhs (object)
         d5e64dc0         24 java.util.regex.Pattern$5        .root.next.atom.val$lhs.val$lhs (object)
         d5e64dd8         24 java.util.regex.Pattern$5        .root.next.atom.val$lhs        (object)
         d5e64df0         24 java.util.regex.Pattern$5        .root.next.atom                (object)
         d5e64e08         32 java.util.regex.Pattern$Curly    .root.next                     (object)
         d5e64e28         24 java.util.regex.Pattern$Single   .root.next.next                (object)
         d5e64e40         24 java.util.regex.Pattern$BitClass .root.next.next.next.atom.val$rhs (object)
         d5e64e58        272 [Z                               .root.next.next.next.atom.val$rhs.bits [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
         d5e64f68         24 java.util.regex.Pattern$1        .root.next.next.next.atom.val$lhs.val$lhs.val$lhs (object)
         d5e64f80         24 java.util.regex.Pattern$1        .root.next.next.next.atom.val$lhs.val$lhs.val$rhs (object)
         d5e64f98         24 java.util.regex.Pattern$5        .root.next.next.next.atom.val$lhs.val$lhs (object)
         d5e64fb0         24 java.util.regex.Pattern$1        .root.next.next.next.atom.val$lhs.val$rhs (object)
         d5e64fc8         24 java.util.regex.Pattern$5        .root.next.next.next.atom.val$lhs (object)
         d5e64fe0         24 java.util.regex.Pattern$5        .root.next.next.next.atom      (object)
         d5e64ff8         32 java.util.regex.Pattern$Curly    .root.next.next.next           (object)
         d5e65018         24 java.util.regex.Pattern$Single   .root.next.next.next.next      (object)
         d5e65030         24 java.util.regex.Pattern$BitClass .root.next.next.next.next.next.atom.val$rhs (object)
         d5e65048        272 [Z                               .root.next.next.next.next.next.atom.val$rhs.bits [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
         d5e65158         24 java.util.regex.Pattern$1        .root.next.next.next.next.next.atom.val$lhs.val$lhs.val$lhs.val$lhs (object)
         d5e65170         24 java.util.regex.Pattern$1        .root.next.next.next.next.next.atom.val$lhs.val$lhs.val$lhs.val$rhs (object)
         d5e65188         24 java.util.regex.Pattern$5        .root.next.next.next.next.next.atom.val$lhs.val$lhs.val$lhs (object)
         d5e651a0         24 java.util.regex.Pattern$1        .root.next.next.next.next.next.atom.val$lhs.val$lhs.val$rhs (object)
         d5e651b8         24 java.util.regex.Pattern$5        .root.next.next.next.next.next.atom.val$lhs.val$lhs (object)
         d5e651d0         24 java.util.regex.Pattern$5        .root.next.next.next.next.next.atom.val$lhs (object)
         d5e651e8         24 java.util.regex.Pattern$5        .root.next.next.next.next.next.atom (object)
         d5e65200         32 java.util.regex.Pattern$Curly    .root.next.next.next.next.next (object)
         d5e65220        120 (something else)                 (somewhere else)               (something else)
         d5e65298         24 java.util.regex.Pattern$Dollar   .root.next.next.next.next.next.next (object)

Las entradas “(algo más)” describen otros objetos en el montón que no forman parte de este gráfico de objetos.

La mejor documentación jol es la muestras jol en el repositorio jol. Los ejemplos demuestran operaciones jol comunes y muestran cómo puede usar jol para analizar los componentes internos del recolector de elementos no utilizados y de la máquina virtual.

  • Esta respuesta debería tener más votos a favor. Sin duda una muy buena opción para comprobar. EDITAR: Verifiqué que esto se agregó este año mientras se hizo la pregunta en ’08. Probablemente la mejor y más fácil opción para hacer lo que OP pidió en este momento.

    – alquileres

    30 de agosto de 2015 a las 19:22


  • El autor de la herramienta escribió una publicación de blog sobre Jol.

    – Miguel

    6 sep 2015 a las 0:37

  • Para determinar el tamaño del objeto “obj”, use: org.openjdk.jol.info.GraphLayout.parseInstance(obj).totalSize();

    – vigor

    19 de enero de 2017 a las 9:26


  • Tenga en cuenta que vmDetails es ahora VM.current().details().

    – Miha_x64

    13 de mayo de 2018 a las 7:35

  • Verificar GraphLayout.parseInstance(instance).toFootprint() Me pareció más útil entender los tamaños de los objetos.

    – Mugen

    2 de abril de 2020 a las 8:37

Accidentalmente encontré una clase java “jdk.nashorn.internal.ir.debug.ObjectSizeCalculator”, que ya está en jdk, que es fácil de usar y parece bastante útil para determinar el tamaño de un objeto.

System.out.println(ObjectSizeCalculator.getObjectSize(new gnu.trove.map.hash.TObjectIntHashMap<String>(12000, 0.6f, -1)));
System.out.println(ObjectSizeCalculator.getObjectSize(new HashMap<String, Integer>(100000)));
System.out.println(ObjectSizeCalculator.getObjectSize(3));
System.out.println(ObjectSizeCalculator.getObjectSize(new int[]{1, 2, 3, 4, 5, 6, 7 }));
System.out.println(ObjectSizeCalculator.getObjectSize(new int[100]));

resultados:

164192
48
16
48
416

  • Lo mismo aquí, estaba probando las otras soluciones propuestas anteriormente y me encontré con ObjectSizeCalculator. Creo que nadie lo mencionó antes, ya que se introdujo recientemente en el JDK 8 como parte del proyecto. Nashorn. Sin embargo, no he encontrado ninguna documentación oficial sobre esta clase en la web.

    –Henrique Gontijo

    16/10/2016 a las 18:26


  • No parece tener en cuenta la longitud de las cadenas. ¿Se trata solo del tamaño en la pila?

    – jontejj

    7 mayo 2017 a las 8:50

  • Tengo un hashmap, donde com.carrotsearch.RamUsageEstimator devuelve aproximadamente la mitad de ObjectSizeCalculator. ¿Cual es verdadero? – ¿Cuál es más confiable?

    – badera

    18 de mayo de 2017 a las 8:36

  • Tenga en cuenta que ObjectSizeCalculator solo es compatible con HotSpot VM

    – kellanburket

    2 de febrero de 2018 a las 21:04


  • Además, jdk.nashorn.internal.ir.debug.ObjectSizeCalculator ya no está presente en JDK 11

    – Martín Vysni

    23 oct 2020 a las 8:55

Avatar de usuario de Boris Terzic
Boris Terzic

Hace unos años Javaworld tenía un artículo sobre cómo determinar el tamaño de objetos Java compuestos y potencialmente anidados, básicamente recorren la creación de una implementación de sizeof() en Java. El enfoque básicamente se basa en otro trabajo en el que las personas identificaron experimentalmente el tamaño de objetos primitivos y típicos de Java y luego aplicaron ese conocimiento a un método que recursivamente recorre un gráfico de objetos para contar el tamaño total.

Siempre será algo menos preciso que una implementación nativa de C simplemente por las cosas que suceden detrás de escena de una clase, pero debería ser un buen indicador.

Alternativamente, un proyecto de SourceForge apropiadamente llamado tamaño de que ofrece una biblioteca Java5 con una implementación sizeof().

PS No use el enfoque de serialización, no hay correlación entre el tamaño de un objeto serializado y la cantidad de memoria que consume cuando está en vivo.

Avatar de usuario de Nick Fortescue
Nick Fortescue

En primer lugar, “el tamaño de un objeto” no es un concepto bien definido en Java. Podría referirse al objeto en sí, con solo sus miembros, el Objeto y todos los objetos a los que se refiere (el gráfico de referencia). Podrías referirte al tamaño en memoria o al tamaño en disco. Y la JVM puede optimizar cosas como Strings.

Entonces, la única forma correcta es preguntarle a la JVM, con un buen generador de perfiles (yo uso TuKit), que probablemente no es lo que quieres.

Sin embargo, según la descripción anterior, parece que cada fila será independiente y no tendrá un gran árbol de dependencias, por lo que el método de serialización probablemente será una buena aproximación en la mayoría de las JVM. La forma más fácil de hacer esto es la siguiente:

 Serializable ser;
 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 ObjectOutputStream oos = new ObjectOutputStream(baos);
 oos.writeObject(ser);
 oos.close();
 return baos.size();

Recuerda que si tienes objetos con referencias comunes este no lo haré da el resultado correcto, y el tamaño de la serialización no siempre coincidirá con el tamaño en la memoria, pero es una buena aproximación. El código será un poco más eficiente si inicializa el tamaño de ByteArrayOutputStream a un valor razonable.

  • Me gusta este enfoque. ¿Qué tan lejos en términos del tamaño del objeto has estado?

    – Berlín Brown

    24 de julio de 2009 a las 17:56

  • Muy simple y efectivo. Otros métodos son demasiado complicados (especialmente dentro de Eclipse RCP). Gracias.

    – marcolopes

    24 de abril de 2012 a las 16:18

  • La serialización no realizará un seguimiento de las variables transitorias, y el método de serialización predeterminado escribe cadenas en UTF-8, por lo que los caracteres ANSI solo ocuparán un byte. Si tiene muchas cuerdas, su tamaño estará tan lejos como para ser inútil.

    – TMN

    9 de julio de 2012 a las 18:45

  • Si bien esto puede no dar el tamaño exacto, para mis necesidades solo necesitaba una comparación entre 2 objetos y SizeOf no se inicializará desde una aplicación web. ¡Gracias!

    – isaac

    30/10/2012 a las 22:57

  • Buena recomendación de TuKit. Otras alternativas son Máquina virtual virtual y jvmmonitor

    – angelcervera

    24 de febrero de 2013 a las 10:46

Avatar de usuario de Yuval
Yuval

Si solo desea saber cuánta memoria se está utilizando en su JVM y cuánto está libre, puede intentar algo como esto:

// Get current size of heap in bytes
long heapSize = Runtime.getRuntime().totalMemory();

// Get maximum size of heap in bytes. The heap cannot grow beyond this size.
// Any attempt will result in an OutOfMemoryException.
long heapMaxSize = Runtime.getRuntime().maxMemory();

// Get amount of free memory within the heap in bytes. This size will increase
// after garbage collection and decrease as new objects are created.
long heapFreeSize = Runtime.getRuntime().freeMemory();

editar: pensé que esto podría ser útil ya que el autor de la pregunta también declaró que le gustaría tener una lógica que maneje “leer tantas filas como sea posible hasta que haya usado 32 MB de memoria”.

  • Me gusta este enfoque. ¿Qué tan lejos en términos del tamaño del objeto has estado?

    – Berlín Brown

    24 de julio de 2009 a las 17:56

  • Muy simple y efectivo. Otros métodos son demasiado complicados (especialmente dentro de Eclipse RCP). Gracias.

    – marcolopes

    24 de abril de 2012 a las 16:18

  • La serialización no realizará un seguimiento de las variables transitorias, y el método de serialización predeterminado escribe cadenas en UTF-8, por lo que los caracteres ANSI solo ocuparán un byte. Si tiene muchas cuerdas, su tamaño estará tan lejos como para ser inútil.

    – TMN

    9 de julio de 2012 a las 18:45

  • Si bien esto puede no dar el tamaño exacto, para mis necesidades solo necesitaba una comparación entre 2 objetos y SizeOf no se inicializará desde una aplicación web. ¡Gracias!

    – isaac

    30/10/2012 a las 22:57

  • Buena recomendación de TuKit. Otras alternativas son Máquina virtual virtual y jvmmonitor

    – angelcervera

    24 de febrero de 2013 a las 10:46

Avatar de usuario de Attila Szegedi
Atila Szegedi

Cuando trabajaba en Twitter, escribí una utilidad para calcular el tamaño profundo de los objetos. Tiene en cuenta diferentes modelos de memoria (32 bits, oops comprimidos, 64 bits), relleno, relleno de subclases, funciona correctamente en estructuras de datos circulares y matrices. Simplemente puede compilar este archivo .java; no tiene dependencias externas:

https://github.com/twitter/commons/blob/master/src/java/com/twitter/common/objectsize/ObjectSizeCalculator.java

  • Szia! Solo me gustaría gritar tu presentación también: las diapositivas 15-20 son excelentes para ayudar a tener una idea instintiva del costo de varias decisiones de estructura de datos. ¡Gracias por publicar eso!

    – Lucas Usherwood

    1 de octubre de 2015 a las 1:58


  • “no tiene dependencias externas” – ¿desde cuándo la guayaba no es una dependencia externa?

    – l4mpi

    11 de enero de 2016 a las 14:21

  • se parece mucho a github.com/JetBrains/jdk8u_nashorn/blob/master/src/jdk/nashorn/… ? :O

    – Francisco

    24 de octubre de 2017 a las 14:02


  • Guave es una dependencia externa.

    – Mert Serimer

    14 de diciembre de 2017 a las 10:33

  • Esta solución no funciona cuando se usa OpenJDK 17

    – Mauricio

    23 de febrero de 2022 a las 1:58

¿Ha sido útil esta solución?