2010-11-06 4 views
5

Comment peut-on connaître la taille d'un objet Java?sizeof java object

Exemple:

class Person{ 
    String name; 
    int age; 

    public Person(String n, int a){ 
     name = n; 
     age = a; 
    } 
} 

Person person = new Person("Andy", 30); 

maintenant comment puis-je connaître la taille de l'objet personne ??

Merci

+3

Pourquoi avez-vous besoin de connaître la taille de l'objet? –

+2

Si vous avez vraiment besoin de savoir ... http://stackoverflow.com/questions/52353/in-java-what-is-the-best-way-to-determine-the-size-of-an-object –

+0

Considérons le scénario où nous avons une mémoire limitée et où l'application a de multiples objets prenant de l'espace, comment pourrions-nous alors identifier quel objet prend plus d'espace et gérer en conséquence. – daydreamer

Répondre

9

La question n'est pas significative, du moins pas sans contexte supplémentaire.

La notion de « taille » en Java est seulement assez bien défini pour les primitives: Un octet est 8 bits (sans surprise) un int est 32 bits, un long 64bit, etc. (voir, par exemple http://download.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html pour une liste complète).

Pour les instances de l'objet, il est plus compliqué, parce que:

  • instances d'objets peuvent (et le plus souvent se) contiennent des références à d'autres instances en interne, vous devez donc décider de compter ces instances dépendantes, et comment. Que faire si plusieurs instances partagent une dépendance?
  • Parfois, des instances d'objet peuvent être réutilisées (par exemple, l'internalisation de java.lang.String, voir http://en.wikipedia.org/wiki/String_interning). Donc, si vous utilisez x objets de taille y, la taille totale peut être inférieure à x * y
  • La JVM dispose de beaucoup de latitude pour implémenter des objets et des instances en interne. Il peut utiliser différentes techniques pour différentes instances (par exemple, le partage de structures de données internes), de sorte qu'il peut ne pas y avoir de "taille" significative à assigner à un seul objet.

Peut-être que vous pourriez expliquer pourquoi vous êtes intéressé par les tailles d'objet. Il existe quelques règles empiriques pour estimer la mémoire heap utilisée par les instances (par exemple, dans la JVM Sun, une instance java.lang.Object utilise 8 octets), mais celles-ci dépendent de la JVM que vous utilisez.

Généralement, si vous voulez connaître l'utilisation de votre tas, utilisez un profileur de mémoire/tas.

Edit:

Eh bien, il y a (au JDK 6) un moyen d'obtenir une approximation de la quantité de mémoire utilisée par un objet: http://download.oracle.com/javase/6/docs/api/java/lang/instrument/Instrumentation.html#getObjectSize%28java.lang.Object%29

Il est encore qu'une approximation ..

-3

Java n'a pas encore d'opérateur construit en sizeof.

Vous pouvez essayer d'utiliser une méthode de sérialisation, en sérialisant un objet en mémoire et en obtenant la taille de ces données, mais cela ne correspond pas nécessairement à la taille souhaitée.

Vous pouvez également avoir une méthode appelée sizeOf(), comme ceci:

// returns the size of this object in bytes 
int sizeOf() 
{ 
    int size = 0; 
    size += name.Length * 2; // each character in name is 2 bytes, no? 
    size += 4; // for n, which is 32 bits = 4 bytes 
} 

Notez que cette mise en œuvre ne comprend pas les métadonnées contenues dans le nom, seul le nombre d'octets nécessaires pour faire le char[] pour elle.

+0

Mais aussi cela ne montrerait pas combien d'en-têtes d'espace ou alors prendre. – thejh

+0

Édité, j'ai ajouté cette information ... honnêtement, je ne pense pas que Java ait jamais été destiné à avoir une telle fonction ... –

+0

Je crois que la sérialisation n'est pas la manière précise de le faire, puisqu'elle ajoute des métadonnées aux objets afin que le processus de dé-sérialisation sache comment reconstruire l'objet – daydreamer

2

Je pense que vous pouvez obtenir quelque chose qui pourrait vous aider si vous faites quelque chose comme ceci:

/* First trigger classloading */ 
    MyObject delegate = new MyObject(); 

    Runtime.getRuntime().gc(); 

    long before = Runtime.getRuntime().freeMemory(); 
    MyObject delegate2 = new MyObject(); 
    long after = Runtime.getRuntime().freeMemory(); 

    System.out.println("Memory used:"+(before-after)); 

Cela vous donnera la réponse, espérons que vous voulez, ou au moins une approximation.

+0

Qu'en est-il des situations multi-thread? Si deux objets de même taille sont attribués en même temps, la valeur de la mémoire utilisée sera deux fois supérieure à la taille voulue. –

+0

Je ferais un petit test contrôlé pour les objets que je veux appeler.Si vous faites cela dans un environnement threadé, alors tous les paris sont désactivés. – Knubo

0

Objets. Pour déterminer l'utilisation de la mémoire d'un objet, nous ajoutons la quantité de mémoire utilisée par chaque variable d'instance au préfixe associé avec chaque objet, généralement 16 octets. Le surcoût inclut une référence à la classe de l'objet, des informations de récupération de place et des informations de synchronisation . De plus, l'utilisation de la mémoire est généralement rembourrée pour être un multiple de 8 octets (mots machine, sur une machine 64 bits ). Par exemple, un objet entier utilise 24 octets (16 octets de de tête, 4 octets pour la variable d'instance d'int, et 4 octets de padding)

Référence: http://www.amazon.com/Algorithms-4th-Edition-Robert-Sedgewick/dp/032157351X

1

Vous pouvez utiliser la bibliothèque sizeof4j pour calculer la taille d'un objet en java comme SizeOf.shallowSize(new Integer(2))