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

Collection et Stream Java Discussion :

[Stockage] String, Object, List, HashMap


Sujet :

Collection et Stream Java

  1. #1
    Membre du Club Avatar de gojira
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    94
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 94
    Points : 55
    Points
    55
    Par défaut [Stockage] String, Object, List, HashMap
    Bonjour,

    Je cherche à comprendre la façon de stocker les informations en java... notamment la logique de la place mémoire.
    En effet j'ai à ma disposition deux fichiers... le premier contient des informations ASCII dans un schéma particulier (MDL SDFile pour ceux qui connaissent). Le fichier fait 6 Go, les données brutes en font au moins 60%.

    Le deuxième fichiers est un simple fichier CSV contentant 44 millions de lignes de deux valeurs numérique (Integer) au format ASCII séparés par un point-virgule d'une taille totale de 800Mo (une bagatelle par rapport au premier)

    Dans un premier temps je parcours mon premier fichier en stockant le contenu dans un objet. Mon Objet est un simple enregistrement contenant les différents champs String et Hashmap<String, String>. Donc pas de compression à la base, je lis le fichier et je stocke ce que j'ai lu dans un objet sous forme de String.

    Je m'aperçois que pour stocker le millions de valeurs du premier fichier, le chargement dans une HashMap de l'ensemble de mes objets, ou d'une List ne me prends pas plus de 100Mo (alors que je me serais attendu à beaucoup plus).

    Lorsque je charge mon fichier CSV de 44 millions de lignes, ça me fait charger des chaines de caractère dans un objet (Enregistrement) ne dépassant pas les 8 caractères de long. Je m'aperçois que j'explose littéralement la JVM...

    Conclusion je ne sais pas comment la jvm stocke les String... mais ce n'est clairement pas comme un fichier ASCII... de plus il apparait que la taille d'une Liste dépend plus du nombre d'enregistrement que de la taille de chaque enregistrement eux-même (au sens pris sur le fichier source).

    Ma question est la suivante. Est-ce que quelqu'un sait comment sont stockées les String en mémoire sur la jvm?
    J'ai remarqué que le stockage dans une HashMap prenait moins de place et moins de ressource qu'une List (en l'occurence j'ai testé sur une ArraList)

    Comparaison HashMap<String, Objet> et ArrayList<Record>
    où Record est un enregistrement de String et Object

    Qu'en pensez vous? Quel en est la raison?

    Je m'excuse si ce message n'a pas sa place ici, car je n'ai pas vraiment de problème à proprement parlé, mais je cherche réellement à comprendre comment ça se passe pour pouvoir optimiser mon code et ma logique algorithmique compte tenu du grand nombre de données manipulées.

    Je vous remercie tous pour m'avoir lu jusqu'au bout et merci d'avance à ceux qui pourraient m'expliquer ce qu'ils ont compris.

    Amicalement

    Gojira
    mon site sur la culture japonaise et le Uechi-ryû: http://www.shinryu.fr

  2. #2
    Rédacteur
    Avatar de CyberChouan
    Homme Profil pro
    Directeur technique
    Inscrit en
    Janvier 2007
    Messages
    2 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 752
    Points : 4 314
    Points
    4 314
    Par défaut
    Si ton fichier texte contient de nombreuses chaînes identiques, il est normal que ça ne prenne "pas tant de place".

    Java maintien en interne un pool de chaînes de caractères. Les objets String étant "immuables", plusieurs chaînes identiques peuvent pointer vers le même espace mémoire sans risque.
    On peut d'ailleurs forcer ce comportement sur une nouvelle instance en utilisant la méthode "intern()" de la classe String.

    Par ailleurs, si tu as une très grosse chaîne, et que tu la découpes au moyen de "substring()", il n'y a pas de mémoire prise pour le texte (uniquement pour la référence) : la nouvelle référence pointe vers l'espace mémoire de la chaîne complète mais avec des indicateurs de début et de fin pour la délimiter.

    C'est pourquoi il ne faut (sauf exceptions rares) pas utiliser "new String("chaine")" qui force la réservation d'un nouvel espace mémoire mais directement "chaine" (afin que la JVM essaye d'optimiser la mémoire en pointant vers une chaîne identique du cache).

    Pour les Integer, un mécanisme de cache similaire peut exister (mais là, ça dépendra des JVM). Pour l'utiliser, même principe : éviter "new Integer(n)" et le remplacer par Integer.valueOf(n).

    Concernant les HashMap, je suis étonné... Avec le stockage de la clé, elle prend normalement plus de place en mémoire qu'une liste (car elle maintien un hash des clé), mais en contrepartie elle permet un accès beaucoup plus rapide aux objets grâce à celui-ci.

    Mon hypoyhèse est que ton analyse a peut-être été faussée à cause d'un passage du "Garbage Collector" qui a récupéré de la mémoire inutilisée lorsque tu as utilisé une HashMap...

    Pour bien comprendre ces mécanismes, tu peux faire des tests avec "==" (qui compare les références des objets) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    String a = "a";
    String b = "a";
    String c = new String("a");
    String d = c.intern();
     
    a == b // Vrai, à cause du cache de la JVM
    a == c // Faux, car on a forcé la création d'une nouvelle instance
    a == d // Vrai, car intern() vérifie la valeur de la chaîne et fait pointer le nouvel objet vers sa version en cache
    Avant de poster, pensez à regarder la FAQ, les tutoriaux, la Javadoc (de la JRE que vous utilisez) et à faire une recherche
    Je ne réponds pas aux questions techniques par MP: les forums sont faits pour ça
    Mes articles et tutoriaux & Mon blog informatique

  3. #3
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Je ne m'explique pas trop comment tu obtiens ces résultats, mais je peux toujours répondre à des questions.

    Citation Envoyé par gojira Voir le message
    Conclusion je ne sais pas comment la jvm stocke les String... mais ce n'est clairement pas comme un fichier ASCII...
    Une String n'est qu'un char[] décoré. Un char est un type de base de 2 octets, et un char[] et composé des chars qu'il contient, plus sa longueur, stockée sur 4 octets.
    Ajouter 12 octets de trucs qui simplifient. Donc, pour une String de longueur n, l'occupation mémoire devrait être environ n*2+4+4+12 = n*2+20 octets, ainsi que 4 octets par référence vers cette String.

    Attention toutefois, les Strings obtenues avec substring() ou issue du pool partagent la mémoire utilisée par d'autres.

    de plus il apparait que la taille d'une Liste dépend plus du nombre d'enregistrement que de la taille de chaque enregistrement eux-même (au sens pris sur le fichier source).
    Hmm, grosso-modo une ArrayList est un Object[]. Sa taille dépend donc de la taille des Objects contenus, ainsi que de la taille du tableau qui les référence. Cela nous fait 4 octets par objet contenu, +50% environ dans le pire des cas de l'algo de redimensionnement du tableau.

    C'est peu, comparé à la taille des Strings.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

Discussions similaires

  1. List<Map<String, Object>> en List<User>
    Par scrutin dans le forum Collection et Stream
    Réponses: 1
    Dernier message: 14/12/2012, 19h06
  2. Conversion string to liste
    Par midos dans le forum Prolog
    Réponses: 3
    Dernier message: 21/02/2010, 09h47
  3. Casting Object en Hashmap
    Par toflofr dans le forum Collection et Stream
    Réponses: 14
    Dernier message: 21/11/2007, 15h29
  4. Réponses: 4
    Dernier message: 03/05/2006, 14h30
  5. Ranger un tableau de String dans ma HashMap
    Par jeyce dans le forum Collection et Stream
    Réponses: 3
    Dernier message: 26/08/2004, 22h41

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