Quantos bytes ocupa o meu objeto na memória?

Tenho um HashMap meio que gigante e gostaria de saber quanto ele está ocupando na memória.

Buscando no Google achei algumas coisas, e uma solução meio esquisita para fazer o que eu quero.

Conversei com o Paulo Silveira e ele comentou sobre um post no blog do MisterM mostrando o uso da java.lang.instrument.
Infelizmente o exemplo dele dá NPE , talvez por eu usar o Mustang e perceber que na versão 6 mudou bastante.

Alguém tem alguma sugestão ? :slight_smile:

A maneira mais boba de estimar o tamanho do hashmap é serializá-lo, e multiplicar o resultado por 2 se o hashmap contiver principalmente Strings ou objetos de classes cujos campos são principalmente Strings.
É porque uma String é serializada para UTF-8, ou seja, se cada caracter ocupa 2 bytes na memória, ao ser serializada a String ocupa apenas 1 byte.

Map meuMapaGigante = new HashMap();
meuMapaGigante.put (...);
ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream ("/teste.bin");
oos.writeObject (meuMapaGigante);
oos.close();

Ou então usar um profiler, que lhe dá a informação correta em vez do tamanho chutado que lhe passei.
Se você estiver usando o Java 5.0 ou 6.0 pode tentar usar o jhat (utilitário que vem junto com o JDK).

[quote=boaglio]
Conversei com o Paulo Silveira e ele comentou sobre um post no blog do MisterM mostrando o uso da java.lang.instrument.
Infelizmente o exemplo dele dá NPE , talvez por eu usar o Mustang e perceber que na versão 6 mudou bastante.[/quote]

Olá Boaglio,

O fato do exemplo não funcionar tem pouco a ver com você estar usando o Mustang e sim pelo fato de eu ter usado o JDK 5 beta, que era o único disponível na época em que escrevi o post, e a API ter mudado pro Java SE 5 final.

Algumas das coisas que mudaram incluem a obrigatoriedade da construção de um jar com o agente, a definição da maioria dos parâmetros que eram passados por comando de linha agora ocorrer como atributos do MANIFEST.MF do jar e outras. Dê uma boa lida na documentação do package java.lang.instrument porque todas estas coisas são explicadas lá.

A única forma mais confiável de calcular o tamanho dos objetos em RAM talvez seja usar a API de debugging do JDK, mas duvido que os resultados entre esta API e o j.l.i variem significativamente.

A diferença entre o tamanho de um objeto serializado e seu tamanho em RAM pode ser brutal devido a diversos fatores. O primeiro e mais óbvio é o formato de serialização e o formato de armazenamento em RAM divergirem, pois o segundo em tese deve ser otimizado para coisas como performance e GC, enquanto o primeiro deveria minimizar o tamanho em disco. Por exemplo, bytes, shorts e ints são armazenados como longs em RAM por algumas VMs, simplesmente porque as operações assembly nativas (e o processo de compilação nativa) acabam sendo mais rápidas se usarem tipos uniformes.

Outro fator é que a spec de serialização prevê mecanismos que permitem a customização do processo, o que possibilitar tornar ainda mais diferente o formato serializado do que seria o formato em RAM.

Um profiler nao faz isso não? (alem de outras coisas é claro)

Obrigado pelas dicas pessoal.

Estou procurando um código de exemplo, alguém poderia indicar ? :slight_smile:

[quote=boaglio]
Estou procurando um código de exemplo, alguém poderia indicar ? :slight_smile: [/quote]

Bem, mais explicado que esse post novo no java.net não dá pra ser. :smiley:

Não tenho certeza mas acho q plugin Eclipse Test & Performance Tools Platform (TPTP) tem como ver isso.

Bom dia,

Você conseguiu descobrir o tamanho em bytes de seu HashMap?

Vlw

A JDK tem uma série de Tools e utilitários que servem exatamente para esse e os mais variados propósitos.

Dê uma olhada nesse em especial que é para o seu problema : http://java.sun.com/javase/6/docs/technotes/tools/share/jmap.html

Aqui você tem a página que descreve os tools - http://java.sun.com/javase/6/docs/technotes/tools/index.html#troubleshoot

Para a versão 5 vc tem um outro software - http://oss.metaparadigm.com/jmemprof/ .

Vi dois artigos bons sobre o tema, mas não falava especificamente de memória e sim profiler via AOP na IBM - http://www-128.ibm.com/developerworks/java/library/j-aopwork10/

Agora se você quiser fazer automaticamente gerando até gráficos, aconselho a utilizar o NetBeans Profiler que era o JFluid , projeto separado da Sun Microsystems … excelente ferramenta, já o utilizei em diversos casos :slight_smile: