IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

Calcul de l'espace occupé par une Collection


Sujet :

Java

  1. #1
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Par défaut Calcul de l'espace occupé par une Collection
    Y a-t-il un moyen de prédire la quantité de mémoire occupée par une collection ? C'est pour faire un choix. Je ne sais pas si je dois arbitrer pour une HashMap, sachant qu'un nouvel objet est crée pour chaque couple [clé, valeur], ou bien si je dois plutôt m'orienter vers un tableau, quitte à écrire moi-même des algorithmes de recherche adaptés précisément à mon cas. Sachant que je pourrais me retrouver à terme avec un très grand nombre d'objets (des chaînes).

    [EDIT] J'arbitrerai plutôt entre une LinkedHashMap et un tableau

  2. #2
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    À mon avis, c'est plus la taille des objets que tu ajoutes qui va prendre de la place plutôt que la structure de la Collection...
    Certes, HashMap sera bien sûr plus volumineux qu'un tableau, mais ça sera négligeable par rapport aux éléments insérés dedans...

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Par défaut
    Ce sera pour faire quelque chose qui ressemblera à un graphe. Le nombre d'arcs augmentera plus vite que le nombre de sommets, d'autant que la JVM utilise un pool pour les chaînes.

  4. #4
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Citation Envoyé par had35
    d'autant que la JVM utilise un pool pour les chaînes.
    ??

    Tu peux expliquer stp?

  5. #5
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Par défaut
    Ben la JVM ne construit pas tout à fait autant de chaînes qu'on le lui demande. Elle garde en mémoire celles qui ont été construites pour les "resservir" au lieu de reconstruire un nouvel objet. Je suppose que le détail du mécanisme est beaucoup plus complexe car il doit en plus être optimisé avec le compilateur. Mais pour faire simple, lorsque je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    String chaine1 = "chaine";
    String chaine2 = "chaine";
    chaine1 et chaine2 sont en fait le même objet.

  6. #6
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Citation Envoyé par had35
    Ben la JVM ne construit pas tout à fait autant de chaînes qu'on le lui demande. Elle garde en mémoire celles qui ont été construites pour les "resservir" au lieu de reconstruire un nouvel objet. Je suppose que le détail du mécanisme est beaucoup plus complexe car il doit en plus être optimisé avec le compilateur. Mais pour faire simple, lorsque je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    String chaine1 = "chaine";
    String chaine2 = "chaine";
    chaine1 et chaine2 sont en fait le même objet.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.out.println("chaine" == "chaine");
    Effectivement, cela renvoie true...

    Très étonnant, pourquoi est-ce qu'au débutant on n'arrête pas de répéter qu'il faut utiliser equals, si 2 chaînes qui sont égales sont le même objet?

    EDIT: C'est que lors d'une déclaration directe, car:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.out.println("chaine".substring(2,3) == "a");
    renvoie false

  7. #7
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Par défaut
    Citation Envoyé par ®om
    pourquoi est-ce qu'au débutant on n'arrête pas de répéter qu'il faut utiliser equals, si 2 chaînes qui sont égales sont le même objet?)
    Parce qui une chaîne est construite à partir d'une tableau de char, cette fois, la JVM crée réellement un nouvel objet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    String chaine1 = "chaine";
    String chaîne2 = new String( new char[]{'c', 'h', 'a', 'i', 'n', 'e'} );
    Cette fois chaine1==chaine2 n'est pas vérifié.

  8. #8
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    D'ailleurs, ceci doit être géré à la compilation pour les chaînes "directes", donc ça ne ralentit même pas l'exécution

  9. #9
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Par défaut
    Citation Envoyé par ®om
    D'ailleurs, ceci doit être géré à la compilation pour les chaînes "directes", donc ça ne ralentit même pas l'exécution
    C'est un des domaines où Java est supérieur à C++ avec ses chaînes STL

  10. #10
    Membre chevronné Avatar de gronono
    Inscrit en
    Novembre 2003
    Messages
    457
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Novembre 2003
    Messages : 457
    Par défaut
    Citation Envoyé par ®om
    pourquoi est-ce qu'au débutant on n'arrête pas de répéter qu'il faut utiliser equals, si 2 chaînes qui sont égales sont le même objet?
    Tester l'égalité deux chaines avec la méthode equals permet de prendre des bonnes habitudes. Et lorsque le débutant travaille avec des objets plus complexe, il ne se pose plus la question : il teste avec equals.

  11. #11
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Citation Envoyé par gronono
    Tester l'égalité deux chaines avec la méthode equals permet de prendre des bonnes habitudes. Et lorsque le débutant travaille avec des objets plus complexe, il ne se pose plus la question : il teste avec equals.
    Je pense que c'est plutôt parce que ce ne sont que les chaines affectées "directement" qui sont physiquement égales si elles sont logiquement égales...

  12. #12
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Par défaut
    Bon, tout ça ne m'aide pas beaucoup à calculer l'espace occupé par une collection

    Je crois que je vais opter pour un tableau, mais si quelqu'un a une solution pour le calcul, je suis toujours intéressé

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 77
    Par défaut
    Citation Envoyé par had35
    Bon, tout ça ne m'aide pas beaucoup à calculer l'espace occupé par une collection

    Je crois que je vais opter pour un tableau, mais si quelqu'un a une solution pour le calcul, je suis toujours intéressé
    Salut, pour calculer la taille d'une collection, tu dois tenir compte de la taille des attributs d'une collection et faire la somme de la taille des objets dans ta collection.

    Par exemple, une ArrayList prend la taille d'un int (le nombre d'éléments dans ta liste) et la taille du tableau, c'est-à-dire la somme de la taille de ses éléments.

  14. #14
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Par défaut
    Citation Envoyé par otsgd
    Salut, pour calculer la taille d'une collection, tu dois tenir compte de la taille des attributs d'une collection et faire la somme de la taille des objets dans ta collection.

    Par exemple, une ArrayList prend la taille d'un int (le nombre d'éléments dans ta liste) et la taille du tableau, c'est-à-dire la somme de la taille de ses éléments.
    Merci pour ta réponse. Comme il s'agit d'un objet, je pense que la taille du tableau doit tendre vers la somme de celle de ses éléments lorsque le nombre d'éléments tend vers l'infini. Mais lorsque le tableau est de taille modeste, les informations relatives à la collection en tant qu'objet ne sont plus négligeables et en plus, les éléments contenus dans la collection sont eux-mêmes des objets. C'est cette quantité d'informations propre à la structure de données Objet qu'il m'intéresserait de calculer. Sachant que je voudrais aussi pouvoir le faire avec une Map pour laquelle cette fois, le calcul ne peut plus se faire à partir de la somme de ses éléments. Je ne sais pas si je suis très clair.

  15. #15
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 77
    Par défaut
    Citation Envoyé par had35
    Merci pour ta réponse. Comme il s'agit d'un objet, je pense que la taille du tableau doit tendre vers la somme de celle de ses éléments lorsque le nombre d'éléments tend vers l'infini.
    Je ne suis pas sûr. Selon moi :
    Espace Occupé par un tableau de String = Longueur du tableau * Espace occupé par une référence + Somme(taille de la String).
    Et ceci est vrai dès la première case. Le tableau pouvant contenir plus de cases que d'éléments.

    Mais lorsque le tableau est de taille modeste, les informations relatives à la collection en tant qu'objet ne sont plus négligeables et en plus, les éléments contenus dans la collection sont eux-mêmes des objets. C'est cette quantité d'informations propre à la structure de données Objet qu'il m'intéresserait de calculer. Sachant que je voudrais aussi pouvoir le faire avec une Map pour laquelle cette fois, le calcul ne peut plus se faire à partir de la somme de ses éléments. Je ne sais pas si je suis très clair.
    Je crois avoir compris. Tu ne pourrais pas faire ça par réflexion sur les objets dont tu veux calculer la taille (une réflexion récursive) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    public long size(Object obj, List fList) throws IllegalAccessException {
       long result = 0;
     
       if (fList == null)
          fList = new ArrayList();
     
          Field f;
          for (int idx = 0; idx < obj.getClass().getDeclaredFields().length; idx++) {
             f = obj.getClass().getDeclaredFields()[idx];
     
    	 if (fList.contains(f))
    	    continue ;
     
    	 fList.add(f);
     
    	 if (f.getType() == int.class)
    	    result += 4; // Je ne suis pas sur pour le 4
    	 // ... sur tous les types primaires
             else {
    	    try {
    	       Object child = f.get(obj);
    	       if (child == null)
    	          result += 4;
    	       else
    	          size(child, fList);
    	     } catch (IllegalAccessException iae) {
    	         iae.printStackTrace();
    	     }
    	 }
          }
     
          return result;
    }
    Il y a sans doute beaucoup à faire, mais ça te donne une idée. Tu n'auras pas accès aux membres statiques (d'ou l'exception). Il y a surement des subtilités de Java dont il faut tenir compte, mais ca peut le faire comme ça. Tu dois traiter à la main les tableaux, les objets de types primaires ...

  16. #16
    Membre émérite Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Par défaut
    Citation Envoyé par had35
    Ce sera pour faire quelque chose qui ressemblera à un graphe. Le nombre d'arcs augmentera plus vite que le nombre de sommets, d'autant que la JVM utilise un pool pour les chaînes.
    Juste pour info, il existe une API qui implemente de nombreuses structures de données, dont les graphes. Vas vers un tour dans la partie API Java de ce site, elle est referencé.

  17. #17
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Par défaut
    Merci otsgd, je vais essayer ce que tu proposes.

    Merci aussi à benratti. Ma structure de données n'est pas tout à fait un graphe, mais je vais quand même jeter un coup d'oeil à ce que proposent les liens vers les apis existantes.

  18. #18
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Par défaut
    Citation Envoyé par otsgd
    Tu ne pourrais pas faire ça par réflexion sur les objets dont tu veux calculer la taille (une réflexion récursive) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    public long size(Object obj, List fList) throws IllegalAccessException {
       long result = 0;
     
       if (fList == null)
          fList = new ArrayList();
     
          Field f;
          for (int idx = 0; idx < obj.getClass().getDeclaredFields().length; idx++) {
             f = obj.getClass().getDeclaredFields()[idx];
     
    	 if (fList.contains(f))
    	    continue ;
     
    	 fList.add(f);
     
    	 if (f.getType() == int.class)
    	    result += 4; // Je ne suis pas sur pour le 4
    	 // ... sur tous les types primaires
             else {
    	    try {
    	       Object child = f.get(obj);
    	       if (child == null)
    	          result += 4;
    	       else
    	          size(child, fList);
    	     } catch (IllegalAccessException iae) {
    	         iae.printStackTrace();
    	     }
    	 }
          }
     
          return result;
    }
    Il y a sans doute beaucoup à faire, mais ça te donne une idée. Tu n'auras pas accès aux membres statiques (d'ou l'exception). Il y a surement des subtilités de Java dont il faut tenir compte, mais ca peut le faire comme ça. Tu dois traiter à la main les tableaux, les objets de types primaires ...
    Je n'ai pas réussi à obtenir d'information intéressante car il semble que l'essentiel des données soit encapsulé.

    Je m'y suis pris finalement de façon indirecte en comparant la taille des fichiers de sérialisation en fonction du nombre de cellules, autrement dit en évaluant le nombre d'octets par cellule. J'ai effectué l'opération avec un tableau, une arraylist et une hashmap et je suis plutôt étonné de constater que la différence n'est pas flagrante. Même la hashmap occupe une taille modeste, à peine le double d'un tableau, et le rapport est sensiblement constant. C'était juste par curiosité car mon framework est déjà avancé.

    Ci-joint l'api que j'ai utilisé. N'hésitez pas à faire des remarques.

    Merci à tous pour votre aide.
    Fichiers attachés Fichiers attachés

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Espace Memoire occupé par une table
    Par guigui76esi dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 17/07/2008, 10h44
  2. Espace occupé par une partie d'une table
    Par besco dans le forum Administration
    Réponses: 1
    Dernier message: 24/10/2007, 16h00
  3. Gestion de l'espace occupé par une valeur null
    Par Oberown dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 01/08/2007, 14h03
  4. [ASA]Espace occupé par une Table
    Par madina dans le forum Sybase
    Réponses: 3
    Dernier message: 17/07/2006, 17h16
  5. Espace occupé par une table
    Par Mihaela dans le forum Oracle
    Réponses: 3
    Dernier message: 18/06/2006, 22h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo