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.
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