Voir mon projet favori, MemoryMeasurer. Un petit exemple:
long memory = MemoryMeasurer.measureBytes(new HashMap());
Vous pouvez également tirer répartition de la mémoire plus qualitative:
Footprint footprint = ObjectGraphMeasurer.measure(new HashMap());
Par exemple, j'utilisé ce dernier pour obtenir la per entry cost of various data structures, où la tête est mesurée en nombre d'objets créés, références, et primitives, au lieu de seulement des octets (ce qui est également faisable). Ainsi, la prochaine fois que vous utiliserez un (par défaut) HashSet
, vous pouvez être informé que chaque élément coûte 1 nouvel objet (pas votre élément), 5 références et un int, ce qui correspond exactement au coût d'une entrée dans HashMap
(pas de façon inattendue, puisque tout élément HashSet
finit dans un HashMap
), et ainsi de suite.
Vous pouvez l'utiliser sur n'importe quel graphe d'objet. Si votre graphe d'objet contient des liens d'autres structures que vous souhaitez ignorer, vous devez utiliser un prédicat pour éviter de les explorer.
ModifierInstrumentation
n'est pas disponible pour Java 1.4 (wow, les gens utilisent encore cette ?!), donc au-dessus de l'appel memoryBytes
ne fonctionnerait pas pour vous. Mais le second le ferait. Ensuite, vous pouvez écrire quelque chose comme ça (si vous êtes sur une machine 32 bits):
long memory = footprint.getObjects() * 8 + footprint.getReferences() * 4 +
footprint.getPrimitives().count(int.class) * 4 +
footprint.getPrimitives().count(long.class) * 8 + ...;
Cela vous donne une approximation. Une meilleure réponse serait de Ceil cela le plus proche multiple de 16:
long alignedMemory = (x + 15) & (~0xF); //the last part zeros the lowest 4 bits
Mais la réponse peut-être encore loin, car si vous trouvez, par exemple, 16 booléens, il est une chose si elles se trouvent dans le même objet, et tout à fait une autre si elles sont réparties dans plusieurs objets (et provoquent une utilisation excessive de l'espace en raison de l'alignement). Cette logique pourrait être implémentée comme visitor (similaire à comment MemoryMeasurer et ObjectGraphMeasurer sont mises en œuvre - tout simplement comme vous pouvez le voir), mais je n'ai pas dérangé, puisque c'est ce que fait Instrumentation
, donc cela n'aurait de sens que pour les versions Java inférieures à 1.5 .
double possible de http://stackoverflow.com/questions/390449/determining-java-memory-usage – nc3b
@ nc3b ce lien traite plus d'environ 1,5. Bien que cela vaut la peine de noter est que l'URL: http://www.javamex.com/tutorials/memory/instrumentation.shtml. J'adorerais avoir ça dans mon java:/ – Gadolin