656 votes

En Java, ce qui est la meilleure façon de déterminer la taille d’un objet ?

Par exemple, disons que j'ai une application qui peut lire dans un fichier CSV avec des tas de lignes de données. Je donne à l'utilisateur un résumé du nombre de lignes basés sur les types de données, mais je veux m'assurer que je ne lis pas dans un trop grand nombre de lignes de données et de la cause OutOfMemory Exceptions. Chaque ligne se traduit par un objet. Est-il un moyen facile de trouver de la taille de cet objet par programmation? Est-il un document de référence qui définit la façon dont les grands types primitifs et les références de l'objet sont pour une VM?

Maintenant, j'ai un code qui dit lire jusqu'à 32 000 lignes, mais j'aimerais aussi avoir un code qui dit lire autant de lignes que possible jusqu'à ce que j'ai utilisé de 32 mo de mémoire. Peut-être que c'est une autre question, mais je voudrais encore savoir.

481voto

Stefan Karlsson Points 2100

Vous pouvez utiliser le paquet java.lang.instrument

Compilez et placez cette classe dans un bocal :

Ajoutez le code suivant à votre `` :

GetObjectSize d’utilisation :

Invoquer avec :

80voto

Boris Terzic Points 6148

Il y a quelques années Javaworld avait un article sur la détermination de la taille de composite et potentiellement imbriquée des objets Java, ils se sont contentés de marcher à travers la création d'un sizeof() mise en œuvre en Java. L'approche s'appuie essentiellement sur d'autres travaux où les gens expérimentalement identifié la taille de primitives et typique des objets Java et ensuite d'appliquer ces connaissances à une méthode récursive de promenades d'un objet graphique compte de la taille totale.

Il est toujours va être un peu moins précis qu'un natif C mise en œuvre simplement parce que de ce qui se passe derrière les coulisses d'une classe, mais il devrait être un bon indicateur.

À l'inverse, un projet sur SourceForge dûment appelé sizeof qui offre un Java5 bibliothèque avec un sizeof() de la mise en œuvre.

P. S. Ne pas utiliser la sérialisation approche, il n'y a pas de corrélation entre la taille d'un objet sérialisé et la quantité de mémoire qu'elle consomme quand live.

71voto

Nick Fortescue Points 18829

Tout d'abord "la taille d'un objet" n'est pas un concept défini dans Java. Vous pourrait signifier que l'objet lui-même, avec ses membres, l'Objet et tous les objets qu'il désigne (le graphique de référence). Vous pourriez dire la taille de la mémoire ou de la taille sur le disque. Et la JVM est autorisé à optimiser des choses comme des Chaînes de caractères.

Donc, la seule façon est de demander à la JVM, qui un bon profiler (j'utilise YourKit), qui n'est probablement pas ce que vous voulez.

Cependant, à partir de la description ci-dessus, il sonne comme chaque ligne sera autonome et ne pas avoir une grande dépendance de l'arbre, de sorte que la méthode de sérialisation sera probablement une bonne approximation sur la plupart des machines virtuelles. La façon la plus simple de le faire est comme suit:

 Serializable ser;
 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 ObjectOutputStream oos = new ObjectOutputStream(baos);
 oos.writeObject(ser);
 oos.close();
 return baos.size();

N'oubliez pas que si vous avez des objets avec des références communes, ce ne sera pas donner le résultat correct, et la taille de la sérialisation pas toujours à la hauteur de la taille en mémoire, mais c'est une bonne approximation. Le code sera un peu plus efficace si vous utilisez le ByteArrayOutputStream une taille raisonnable de la valeur.

40voto

matt b Points 73770

Si vous comme de savoir combien de mémoire est utilisé dans votre machine virtuelle Java, et combien est gratuit, vous pouvez essayer quelque chose comme ceci :

Edit : J’ai pensé que cela pourrait être utile que l’auteur de la question a également déclaré qu’il voudrait logique qui gère « lire autant de lignes que possible jusqu'à ce que j’ai utilisé 32 Mo de mémoire. »

12voto

Jason Cohen Points 36475

Vous avez à marcher objets à l'aide de la réflexion. Veillez à ce que vous faites:

  • Juste l'allocation d'un objet a une surcharge dans la JVM. Le montant varie en fonction de la JVM de sorte que vous pourriez faire de cette valeur d'un paramètre. De faire au moins une constante (8 octets?) et pour tout ce qui est attribué.
  • Juste parce qu' byte est théoriquement 1 octet ne signifie pas qu'il suffit d'un seul dans la mémoire.
  • Il y aura des boucles dans les références de l'objet, de sorte que vous aurez besoin de garder un HashMap ou somesuch de l'objet est égale à la comparaison afin d'éliminer les boucles infinies.

@jodonnell: j'aime la simplicité de votre solution, mais de nombreux objets ne sont pas Sérialisables (donc, ce serait jeter une exception), les champs peuvent être transitoires, et les objets peuvent remplacer les méthodes standard.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X