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

Entrée/Sortie Java Discussion :

Newsgroup et mémoire


Sujet :

Entrée/Sortie Java

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 14
    Points : 9
    Points
    9
    Par défaut Newsgroup et mémoire
    Bonjour,


    J'ai commencé à écrire un petit client pour récupérer des fichier et lire des articles sur les newsgroups et parcourir les groupes à la main. J'utilise commons/net pour accéder au newsgroups, et ça marche plutôt bien, mais je suis confronté à des problèmes de mémoire.

    Déjà, mon interface graphique fait presque 30 Mo alors qu'elle est vide, j'hallucine


    (le java du bas c'est netbeans, celui du haut mon programme, NewsMotte)

    Mais bon c'était pas pour ça que je venais sur le forum.

    Mes deux interrogations sont les suivantes :

    D'une part, comment je peux gérer mon groupe de socket (vu que les fournisseurs d'accès aux news autorisent plusieurs connexions simultanées). De ce que j'ai lu, un sémaphore qui utiliserait autant de 'jetons' que de connexions serait adapté, mais comme je ne m'en suis encore jamais servi je voulais savoir si c'était une bonne idée ?

    D'autre part, en ce moment j'étais entrain de faire l'exploration des groupes, donc je peux lister tous les groupes, en sélectionner un et afficher son contenu. Le détail c'est qu'il y a quand même un sacré paquet de groupes (plus ou moins 70000 en comptant les groupes vides) et un sacré paquet d'articles surtout dans les gros groupes et vu que je charge tout en mémoire puis je l'affiche, ça fait beaucoup beaucoup trop de mémoire utilisée : / Genre je peux pas afficher le contenu de deux ou trois groupes simultanément sinon je dépasse 1Go d'utilisation de ram : /

    Je commence donc à me dire qu'il faudrait peut être les stocker sur le disque dur plutôt que dans la ram, mais je ne sais pas trop comment faire ça pour que les perfs et la conso mémoire restent acceptables. J'ai fait quelques essais avec grabIt, et visiblement il sauvegarde tous les headers dans un fichier et les affiche en lisant directement depuis le fichier car il ne dépasse même pas 12Mo de consommation mémoire (alors que les headers peuvent dépasser 200 Mo).


    Edit :
    Concernant la mémoire occupée lors du traitement de la liste de groupe et/ou des articles, je pense qu'il faut jouer avec RandomFileAccess et/ou avec la sérialisation. Mais je sais pas encore comment ...

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 807
    Points
    48 807
    Par défaut
    Citation Envoyé par MoMotte Voir le message

    Déjà, mon interface graphique fait presque 30 Mo alors qu'elle est vide, j'hallucine
    non tu n'hallucine pas. Par contre, ce qui compte en occupation mémoire, c'est ce que te retourne Runtime.getRuntime().freeMemory(), Runtime.getRuntime().totalMemory() et Runtime.getRuntime().maxMemory.

    La mémoire affichée sous linux regroupe non seulement ton application, mais l'ensemble des librairies auxquelles elle est reliée ainsi que l'ensemble des ressource mappées en mémoire (fichiers ouverts, etc).

    Citation Envoyé par MoMotte Voir le message
    et vu que je charge tout en mémoire puis je l'affiche, ça fait beaucoup beaucoup trop de mémoire utilisée : / Genre je peux pas afficher le contenu de deux ou trois groupes simultanément sinon je dépasse 1Go d'utilisation de ram : /
    C'est pourquoi les client newsgroup sur le marché font

    1) du stockage sur disque (pour éviter de recharger les messsage à chaque démarrage)
    2) ne chargent que les groupe ouverts à l'écran
    3) ne s'inscrivent qu'aux groupes demandés par l'utilisateur
    4) ne chargent en mémoire que les entêtes, et encore, pas nécessairement tous

    En java tu va trouver un outil fort pratique pour t'aider à faire la balance entre l'occupation mémoire et le rechargement (que ce soit depuis le disque ou les socket), c'est le SoftReference: http://java.sun.com/j2se/1.4.2/docs/...Reference.html, qui est nettoyé lorsque la memoire viens à manquer. T'as plus qu'à garder des hardreferences sur les trucs ouvert, et des softreference sur les récement ouvert. Ainsi tu garde els trucs récent, sans empecher leur nettoyage par le garbage collector (mais le plus tard possible).

    aussi, oublie la sérialization, utilse plutot un format MIME pour le stockage des news (à faire toi même).

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 14
    Points : 9
    Points
    9
    Par défaut
    Les méthodes de Runtime me donnent des chiffres encore pire que ceux du moniteur système
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Mémoire libre 44 Mo
    Mémoire max 733 Mo
    Mémoire totale 46 Mo
    Enfin c'est pas l'essentiel ça.

    Effectivement les SoftReferences risquent de m'être bien utiles, je vois pas encore très bien comment m'en servir mais je trouverai, je me fais pas trop de soucis là dessus.
    Je suis tombé sur ça : http://articles.techrepublic.com.com...-1049545.html#
    http://articles.techrepublic.com.com...-1049546.html# , je pense qu'en faisant des essais je m'en sortirai

    aussi, oublie la sérialization, utilse plutot un format MIME pour le stockage des news (à faire toi même).
    Là par contre, je veux bien une piste parce que je sais vraiment pas comment faire ça, encore moins comment le faire bien.

  4. #4
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 807
    Points
    48 807
    Par défaut
    çà reseemble à un format mail. en gros tu tappe directement dans le fichier le message du newsgroup, éventuellement sans son corps (voir comment les autres logiciels font). En tout cas, évite la sérialisation, c'est pas performant.

    Pour ce qui est de l'occupation mémoire, le message est claire: la heap de jvm occupe 46M dont 44M sont disponible. Tu n'occupe donc que 2M. C'est du a l'allocation mémoire java, qui alloue par bloc. Dans les jvm récente, le bloc initial est fonciton de la mémoire système totale. Pour réduire, utilise par exemple -Xms10m sur ta ligne de commande, mais c'est franchement peu utile.

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 14
    Points : 9
    Points
    9
    Par défaut
    pour la mémoire ...
    Je sais pas comment j'ai lu les résultats mais sur le coup ça m'avait pas paru normal, maintenant avec les deux yeux ouverts les neurones en place c'est vrai que c'est plutot rassurant en fait

    Sinon c'est clair que quand je liste le contenu d'un groupe, je ne prends que les entêtes, et pas les corps d'article. Vu que rien que les entêtes dépassent 100 Mo, j'ai bien peur que le type mime ne réponde pas à mes attentes.

    Je détaille un peu :
    l'entête d'un article se présente sous la forme d'une String, contenant 7 valeurs séparées par \t(le sujet, la date, le poster, ...). Donc je pourrai écrire directement ces chaînes dans un fichier mais ça c'est bien uniquement pour le stockage d'un lancement à l'autre du programme (le point 1 de ton post précédent).
    Le problème c'est qu'au moment où je dois afficher le contenu du groupe (donc du fichier) dans une JTable, je me demande comment faire pour ne pas charger la totalité du fichier dans la ram (plus j'y pense plus je me dis que c'est pas possible de faire ce que je veux faire :s).

    Pour revenir sur les SoftReferences, sachant que l'affichage du contenu des groupes se fait dans des onglets, ce que tu proposais c'était de passer tous les onglets qui n'ont pas le focus en SoftReferences, ou de les passer en SoftReferences qu'une fois l'avoir fermé (en supposant donc que si l'utilisateur ré-ouvre le groupe, le chargement devrait être quasi immédiat si le GC n'a pas fait le ménage) ?

    Sinon je me demandais comment grabit faisait, donc j'ai regardé les fichiers temp ... ce qui ne m'a rien appris dutout : /
    J'y ai vu trois fichiers qui ne contiennent pas de texte (du binaire, un beau paquet de hiéroglyphes ...) un fichier "analyzed", un "new" et un "cache". Je sais pas si toi ça te parle, mais perso je sais pas comment utiliser cette information

    Merci de prendre le temps de répondre au fait, je ne l'avais pas fait précédemment

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 14
    Points : 9
    Points
    9
    Par défaut
    Je fais remonter le thread parce que je ne m'en sors toujours pas avec ça : /

    Je fais un petit point sur là où j'en suis :

    - On se positionne dans le cas où on veut lister les entêtes d'un gros groupes.
    ex: alt.binaries.boneless (5 millions d'entêtes avec une petite rétention)
    - Vu que j'affiche la liste des entêtes dans une JTable, je défini un tablemodel, donc entre autre getElementAt dont le traitement doit être rapide, vu que cette méthode est appelée pour chaque case de la jtable ; vu que ma JTable a 7 colonnes, dans le cas de boneless ça fait 7 millions * 5 appels de getElementAt (d'où la nécessité d'un traitement pas trop long).

    Vu que je ne peux pas stocker les entêtes en mémoire (on dépasse les 700 Mo), je pensais essayer de les écrire sur le disque et utiliser un randomaccessfile pour avoir un temps d'accès constant, mais j'ai bien peur que ça ne suffise pas (je suis entrain de tester ça) car même si le temps d'accès est constant, il va être constant vis-à-vis du temps d'un appel système, ce qui est relativement long quand on a plusieurs dizaines de millions d'appels systèmes à faire : /

    Je recherche donc une solution, soit pour stocker tout ça mieux, soit pour télécharger moins d'entêtes, mais je ne vois pas trop comment faire le "tri".

  7. #7
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 807
    Points
    48 807
    Par défaut
    L'autre solution, c'est d'utiliser un JTable dont la taille des colonnes / lignes est fixe. CA évite que le JTable aie besoin de tout scanner pour faire son layout. Parce que, scanner tout c'est bien si t'as 1000 entrées, après çà deviens galère!

    Après tout, t'as pas besoin de taille "idéal" pour tes colonnes, une taille fixée peut faire l'affaire. Pour éviter ces longs appels en vue de calculer la largeur de colonne, tu peux, par exemple, implémenter ton propre TableColumnModel. Disons que jtable n'est pas prévu pour 7 millions d'entrées. Tu va peut etre devoir chercher un composant plus performant ou le code toi même. Le but c'est de faire tes calculs à partir d'un ensemble limité d'information:
    le nombre d'enregistrement,
    la peut etre 100aine d'enregistrement visible dans le viewport.

    Le premier te permet de connaitre la taille du jscrollpane, les autres te permettent de dessiner la partie visible.

Discussions similaires

  1. fichier mappé en mémoire
    Par WinBernardo dans le forum Delphi
    Réponses: 7
    Dernier message: 01/12/2006, 09h38
  2. Accéder à un espace mémoire sous XP
    Par keny dans le forum x86 32-bits / 64-bits
    Réponses: 4
    Dernier message: 02/08/2002, 12h37
  3. Déterminer l'adresse d'une application en mémoire
    Par Gib dans le forum x86 32-bits / 64-bits
    Réponses: 9
    Dernier message: 11/06/2002, 14h27
  4. Vitesse de la mémoire vidéo
    Par Anonymous dans le forum x86 16-bits
    Réponses: 3
    Dernier message: 06/06/2002, 20h20
  5. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10

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