2010-10-27 15 views
8

Quelle est la bonne façon de mesurer combien de mémoire du tas devrait être utilisé pour créer un nouvel objet d'un certain type (parlons des entiers pour le garder simple)?Quelle quantité de mémoire est allouée à un objet entier dans Java? Comment trouver cette valeur pour un objet personnalisé?

Cette valeur peut-elle être calculée sans expérience? Quelles sont les règles dans ce cas? Ces règles sont-elles strictement spécifiées quelque part ou peuvent-elles varier de jvm à jvm?

+0

Ils ne varient pas par machine, mais il n'y a pas d'opérateur sizeof dans java si c'est ce que vous demandez – Cratylus

Répondre

14

Il peut varier de JVM à JVM.

Vous pouvez aimer this blog post d'un ingénieur Oracle:

Dans le cas d'un Java entier sur une machine virtuelle Java Hotspot 32 bits, la charge utile 32 bits (un champ Integer.value) est accompagnée d'une 96 bits supplémentaires, une marque, un klass et un mot de remplissage d'alignement, pour un total de 128 bits. De plus, s'il y a (disons) six références à cet entier dans le monde (threads plus tas), ces références occupent aussi 192 bits, pour un total de 320 bits. Sur une machine 64 bits, tout est deux fois plus grand, au moins à l'heure actuelle: 256 bits dans l'objet (qui comprend maintenant 96 bits de remplissage), et 384 bits ailleurs. En revanche, six copies d'un entier primitif Unboxed occupent 192 bits

0

Ce n'est pas facile à faire en Java: sizeof n'existe pas et des solutions de rechange, comme la sérialisation des objets dans un flux d'octets et en regardant le flux résultant de longueur, ne fonctionne pas dans tous les cas (par exemple, les cordes).

Cependant, voir this quite complicated implementation en utilisant des graphiques d'objets.

+1

vous avez probablement lié ce fil dans votre réponse par erreur :) – Roman

+0

@Roman, whoops, erreur éditée :) –

1

Vous pourriez vouloir regarder l'instrumentation de Java pour découvrir cela. Here est un exemple de la même chose. Dans votre cas, comme je crois que vous voulez trouver la taille des objets de votre application, vous rendrez l'objet Instrumentation disponible globalement (static) afin que vous puissiez y accéder à partir de votre application.

code Copié à partir du lien:

public class MyAgent { 
    private static volatile Instrumentation globalInstr; 
    public static void premain(String args, Instrumentation inst) { 
    globalInstr = inst; 
    } 
    public static long getObjectSize(Object obj) { 
    if (globalInstr == null) 
     throw new IllegalStateException("Agent not initted"); 
    return globalInstr.getObjectSize(obj); 
    } 
} 

Cependant, je crois que vous serez en mesure de trouver la taille des objets seulement (pas les types primitifs, vous ne nécessitent pas de les trouver comme vous déjà les connaître :-))

Notez que la méthode getObjectSize() ne comprend pas la mémoire utilisée par d'autres objets référencés par l'objet passé. par exemple, si objet a est une référence à Ob ject B, alors l'utilisation de la mémoire rapportée de l'objet A inclura seulement les octets nécessaires pour la référence à l'objet B (généralement 4 octets), pas l'objet réel.

Pour obtenir un compte « profond » de l'utilisation de la mémoire d'un objet (ie qui comprend « sous-objets » ou des objets visés par l'objet « principal »), vous pouvez utiliser l'agent Classmexer disponible pour téléchargement bêta à partir du site this.