Calcular o tamanho do object em Java

Eu quero registrar quanta memory (em bytes, espero) um object ocupa para um projeto (estou comparando tamanhos de estruturas de dados) e parece que não há nenhum método para fazer isso em Java. Supostamente, C / C ++ tem o método sizeOf() , mas isso é inexistente em Java. Eu tentei gravar a memory livre na JVM com Runtime.getRuntime().freeMemory() antes e depois de criar o object e, em seguida, gravar a diferença, mas daria apenas 0 ou 131304, e nada entre, independentemente do número de elementos na estrutura. Ajuda por favor!

Você pode usar o pacote java.lang.instrumentation :

http://docs.oracle.com/javase/7/docs/api/java/lang/instrument/Instrumentation.html

Ele possui um método que pode ser usado para obter a aproximação específica da implementação do tamanho do object, bem como a sobrecarga associada ao object.

A resposta que Sergey ligou tem um ótimo exemplo, que eu vou repassar aqui, mas você já deveria ter olhado do comentário dele:

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

Use getObjectSize:

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

Fonte:

Em Java, qual é a melhor maneira de determinar o tamanho de um object?

Olhe para https://github.com/DimitrisAndreou/memory-measurer. O Guava o usa internamente, e o ObjectGraphMeasurer é especialmente simples de usar, sem nenhum argumento de linha de comando especial.

 import objectexplorer.ObjectGraphMeasurer; public class Measurer { public static void main(String[] args) { Set hashset = new HashSet(); Random random = new Random(); int n = 10000; for (int i = 1; i <= n; i++) { hashset.add(random.nextInt()); } System.out.println(ObjectGraphMeasurer.measure(hashset)); } } 

A class java.lang.instrument.Instrumentation fornece uma boa maneira de obter o tamanho de um object Java, mas requer que você defina um premain e execute seu programa com um agente java. Isso é muito chato quando você não precisa de nenhum agente e, em seguida, você precisa fornecer um agente Frasco para sua aplicação.

Então eu consegui uma solução alternativa usando a class Unsafe do sun.misc . Portanto, considerando o alinhamento de heap de objects de acordo com a arquitetura do processador e calculando o deslocamento máximo do campo, é possível medir o tamanho de um object Java. No exemplo abaixo eu uso uma class auxiliar UtilUnsafe para obter uma referência ao object sun.misc.Unsafe .

 private static final int NR_BITS = Integer.valueOf(System.getProperty("sun.arch.data.model")); private static final int BYTE = 8; private static final int WORD = NR_BITS/BYTE; private static final int MIN_SIZE = 16; public static int sizeOf(Class src){ // // Get the instance fields of src class // List instanceFields = new LinkedList(); do{ if(src == Object.class) return MIN_SIZE; for (Field f : src.getDeclaredFields()) { if((f.getModifiers() & Modifier.STATIC) == 0){ instanceFields.add(f); } } src = src.getSuperclass(); }while(instanceFields.isEmpty()); // // Get the field with the maximum offset // long maxOffset = 0; for (Field f : instanceFields) { long offset = UtilUnsafe.UNSAFE.objectFieldOffset(f); if(offset > maxOffset) maxOffset = offset; } return (((int)maxOffset/WORD) + 1)*WORD; } class UtilUnsafe { public static final sun.misc.Unsafe UNSAFE; static { Object theUnsafe = null; Exception exception = null; try { Class uc = Class.forName("sun.misc.Unsafe"); Field f = uc.getDeclaredField("theUnsafe"); f.setAccessible(true); theUnsafe = f.get(uc); } catch (Exception e) { exception = e; } UNSAFE = (sun.misc.Unsafe) theUnsafe; if (UNSAFE == null) throw new Error("Could not obtain access to sun.misc.Unsafe", exception); } private UtilUnsafe() { } } 

Uma pesquisa no google sobre “Java sizeof” resultou em um bom artigo sobre Java sizeof no javaworld. Na verdade, uma leitura interessante.

Para responder à sua pergunta, não há um equivalente em Java de “sizeof ()”, mas o artigo descreve algumas maneiras de obter o tamanho de byte de suas classs instanciadas.