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 :

surcharge de la gestion du cache java


Sujet :

Java

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 6
    Points : 5
    Points
    5
    Par défaut surcharge de la gestion du cache java
    Bonjour,

    Voila, j'ai besoin de mettre en place une gestion personnalisée du cache d'une application java. Je tiens à préciser que je ne suis pas très bon dans ce langage.
    Pour le moment, ce qu'il se passe c'est que j'ai des objet (type article à afficher dans mon appli) et ceux-ci remplissent la mémoire cache du pc jusqu'a utiliser plus de 1.5 go de ram. Ce n'est évidemment pas acceptable. C'est pourquoi je me suis renseigné sur le sujet et j'ai pu trouvé une solution qui me semble honnete : LRU cache qui consiste à supprimer du cache les objets les plus vieux (comme pour une liste FIFO) dès lors que qu'une taille limite du cache est atteinte.

    voici la classe que j'ai trouvé sur internet.

    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    import java.util.*;
     
    public class LRUCache {
     
        private static final int MAX_SIZE = 1;
     
        private Map[] backend;
        private int size = 0;
     
        public LRUCache(int n)
        {
            backend = new Map[n];
            for (int i = 0; i < n; i ++)
                backend[i] = new HashMap();
        }
     
        public int size()
        {
            return size;
        }
     
        public Object get(Object key)
        {
            for (Map m : backend) {
                if (m.containsKey(key))
                    return m.get(key);
            }
            return null;
        }
     
        public Object put(Object key, Object value)
        {
            if (backend[0].containsKey(key))
                return backend[0].put(key, value);
            int n = backend.length;
            for (int i = 1; i < n; i ++) {
                Map m = backend[i];
                if (m.containsKey(key)) {
                    Object old = m.remove(key);
                    backend[0].put(key, value);
                    return old;
                }
            }
            backend[0].put(key, value);
            size ++;
            while (size > MAX_SIZE) {
                size -= backend[n - 1].size();
                System.arraycopy(backend, 0, backend, 1, n - 1);
                backend[0] = new HashMap();
            }
            return null;
        }
    }
    Voila où je bloque. En effet, comment mettre concrètement en place ce système de cache ? Dès lors que j'instancie mon objet Article, celui va se mettre en cache, on est d'accord. Du coup j'aimerai l'intercepter au moment de son instanciation afin de savoir si je dois laisser de la place dans le cache, enfin j'imagine ... Pour le moment l'application met en cache de manière transparante les objets ainsi instanciés. J'ai besoin de rendre visible cette procédure de mise en cache via une surcharge de la mise en cache. J'espère être à peu pret clair ...

    Quelqu'un serait m'aider dans cette tache ?? mon cerveau n'en peut plus ...

    Merci d'avance

  2. #2
    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
    Il n'y a pas de cache général Java, il y en a un pour chaque aspect de technologie où un cache se justifie. Et ils ne font pas exploser la mémoire comme cela. On ne peut donc pas "changer le cache Java" car ça n'existe pas, "le cache Java."

    Si tu as un problème de cache, il ne vient pas de Java lui-même mais d'un système de cache que tu as fait toi-même ou que tu as récupéré d'ailleurs.
    Je soupçonnerais plutôt que tu as un problème de fuite mémoire, par exemple que tu gardes en mémoire par erreur des objets que tu ne souhaitais pas garder en mémoire. Peu probable, mais possible aussi que le garbage-collector laisse simplement la mémoire se remplir jusqu'à la limite autorisée avant de forcer la désallocation des objets. Si cela arrive vraiment, il suffit d'ordonner à ta JVM une limite maximum de mémoire plus basse, par exemple avec java -Xmx512M LaClasse pour limiter à 512Mo maximum.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Modérateur
    Avatar de kolodz
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2008
    Messages
    2 211
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 211
    Points : 8 316
    Points
    8 316
    Billets dans le blog
    52
    Par défaut
    Java alloue dynamiquement la mémoire pour les applications.
    A chaque création d'objet la machine virtuel vérifie si l'espace mémoire déjà alloué à l'application est suffisante pour le stockage du nouvel objet.
    Si ce n'est pas le cas, la machine virtuel augmentera la taille mémoire de l'application. (Celui-ci étant limité par certains paramètres de lancement comme -Xmx512M)

    Si une application Java a une taille mémoire importante, cela est dû au fait que la machine virtuelle n'est pas capable de nettoyé les objets qui ne sont plus utilisé par l'application. (Car toujours référencés).

    Si tu veux réellement réduire l’empreinte mémoire de ton application. Il faut que tu regarde quel sont les objets qui occupent ton espace mémoire. Et vérifier si ceux-ci devrai effectivement être présent. Des listes d'objets volumineux déclarées en statique par exemple. Ou une liste d'historique qui n'a pas de limite de taille et donc référence des objets que ne devraient plus exister.

    Il n'y a donc pas de gestion de "Cache" en Java. Mais, une gestion de la mémoire et celle-ci est propre à la Machine Virtuel Java.

    Cordialement,
    Patrick Kolodziejczyk.

    source :
    http://schmitt.developpez.com/tutoriel/java/memoire/
    Si une réponse vous a été utile pensez à
    Si vous avez eu la réponse à votre question, marquez votre discussion
    Pensez aux FAQs et aux tutoriels et cours.

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Merci pour ta réponse thelvin. Je suis d'accord avec toi quand tu dis que Java se charge lui même de vider du cache les objets instanciés inutilisés.
    Pourtant voila ce qu'il se passe au niveau de la mémoire du processus :

    1 - Mon application se lance (processus monte a 200mo)
    2 - Je clique sur le bouton pour visionner un article (250mo => monté en charge donné pour l'exemple, pas forcement exacte)
    3 - Je passe à la lecture d'un autre article (300mo)

    Si je réitère l'action 2, le temps de chargement de l'article est quasi null par rapport à son premier chargement. En fait, plus j'ouvre successivement les articles plus la mémoire du processus augmente. Et donc lorsque je retourne sur ces articles, l'affichage est instantané. Je souhaite que passé une certaine limite, le cache se vide en partie en vidant ce qu'il a de plus vieux. C'est le principe du LRU : least recently used (moins récemment utilisé). Ce principe est expliqué ici (cliquer pour suivre le lien).

    Pour te répondre kolodz (merci de ton aide), comment puis-je voir les objets concervés en mémoire et agir pour les supprimer manuellement ? Parce qu'en effet la JVM doit penser devoir les concerver en mémoire.

  5. #5
    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
    Citation Envoyé par neo6583 Voir le message
    Merci pour ta réponse thelvin. Je suis d'accord avec toi quand tu dis que Java se charge lui même de vider du cache les objets instanciés inutilisés.
    Ça ce n'est pas un cache, c'est juste la mémoire normale.
    Si ton programme garde les précédents objets, c'est parce que tu les as rangés dans une structure qui n'a rien à voir avec un "cache Java," afin de ne pas les perdre. C'est cette structure que tu dois remplacer par un cache LRU.


    Citation Envoyé par neo6583 Voir le message
    comment puis-je voir les objets concervés en mémoire et agir pour les supprimer manuellement ? Parce qu'en effet la JVM doit penser devoir les concerver en mémoire.
    Certains outils de monitoring comme YourKit peuvent le faire... Mais il y a moins compliqué : tes objets, si tu peux les retrouver rapidement, c'est que tu les as gardés quelque part. Eh bien ils sont là. C'est l'endroit d'où tu vas les prendre quand tu les affiches à nouveau.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Bon je reviens pour faire un constat après bon nombre de recherches sur les causes de cette montée en mémoire de mon application. Déjà cette montée s'apparente plutôt à une fuite mémoire. Les références de mes objets articles sont utilisées alors même que je ne suis plus sur cet article. Je pense qu'au niveau du code, il y a des choses à améliorer de ce point de vue.

    Par contre, bon courage pour modifier tout ça. En fait, pour que tout le monde comprenne, chaque objet articles est la résultante d'un fichier html ouvert pour ensuite le placer dans un conteneur java. Ce fichier html, d'habitude assez léger, est dans ce cas précis, assez long et contient beaucoup d'images (type jpg). Ce sont ces images qui sont responsables de cette montée en mémoire. Après savoir si ces fuites mémoires viennent directement de ces images ou bien de chaque objet article c'est une autre question...
    L'import de ces fichiers html est le seul moyen d'afficher le contenu des articles. Cette procédure ne peut malheureusement pas être modifiée (contrainte du projet).

    Voila la problématique. En définitive, c'est le protocole d'affichage du contenu qui pour moi est la base du problème. Et comme ce dernier ne peut être modifié, me voila bien embêté ....

  7. #7
    Membre éclairé Avatar de JoeChip
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 536
    Points : 803
    Points
    803
    Par défaut
    On ne peut pas tout conserver en mémoire sans finalement la saturer... Dans ton cas, le problème c'est que tu stocke tout... Pour libérer la mémoire il suffit que plus rien ne référence l'objet. Autrement dit, son temps de vie en mémoire doit être limité à la visualisation, ou pas loin. Ensuite rien n'empêche de stocker localement l'objet, et de libérer la mémoire qu'il occupe : s'il faut le recharger ensuite, il suffit de voir s'il n'est pas déjà sur le disque dur (ça chargera vite), et d'aller le chercher sur le net s'il n'y est pas.
    Sans danger si utilisé conformément au mode d'emploi.

    (anciennement BenWillard, enfin moins anciennement que ... enfin bon c'est une longue histoire... Un genre de voyage dans le temps...)

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    D'abord merci de ta réponse Joechip,

    Tu as bien résumé ce qu'il faut faire. Maintenant, j'essaie de trouver la façon d'arriver à ce que cet objet ne soit plus référencé. D'àprès mes recherches le garbage collecteur supprime l'objet dès lors que celui n'est plus référencé par une tierce classe. Mais dans mon cas, j'avoue éprouver un mal fou à trouver où il peut l'être.

    Solution manuelle ? N'est-il pas possible de tout simplement supprimer cette objet manuellement ? Un processus inverse du "new" ?

  9. #9
    Membre chevronné
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Points : 1 984
    Points
    1 984
    Par défaut
    Citation Envoyé par neo6583 Voir le message
    Solution manuelle ? N'est-il pas possible de tout simplement supprimer cette objet manuellement ? Un processus inverse du "new" ?
    Non. Pour faire ca, il faut faire du C/C++
    Pouvoir supprimer des objets utilisés par une autre classe ne sera jamais une vraie solution. Pour masquer un probleme de conception facile a cerner, tu risquerais de creer un probleme complexe a debugger.
    Si j'ai bien suivi, c'est dans la map que tu stockes les données concernant les pages. Tu peux donc mettre une regle qui enleve l'objet si il est trop gros/ancien/... en utilisant map.remove().

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Ah mais voila une piste intéressante !

    En effet ces objets sont stockés dans le map. Donc oui le map.remove(key_reference) semble très approprié.
    A moi de supprimer la bonne "key_reference" maintenant. Je vais regarder ça ! Merci encore pour l'aide



    Ps: comme précisé plus haut je suis novice en java.

  11. #11
    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
    Citation Envoyé par hwoarang Voir le message
    Non. Pour faire ca, il faut faire du C/C++
    Et ça ne suffit même pas -_-°. C/C++ n'est pas un langage magique. Si on désalloue un objet sans savoir qui gardait une référence vers lui, ça veut dire qu'on a corrompu la mémoire et qu'elle peut désormais être lue ou modifiée n'importe où par n'importe quoi.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  12. #12
    Membre chevronné
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Points : 1 984
    Points
    1 984
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Et ça ne suffit même pas -_-°. C/C++ n'est pas un langage magique. Si on désalloue un objet sans savoir qui gardait une référence vers lui, ça veut dire qu'on a corrompu la mémoire et qu'elle peut désormais être lue ou modifiée n'importe où par n'importe quoi.
    Oui, j'ai jamais dit que ca poserait pas de probleme Mais ca n'empeche pas que ce serait possible de liberer la mémoire. De toute facon, plus sérieusement, je ne vois pas comment ca pourrait ne pas etre un probleme de désallouer une instance utilisée par un petit copain sans rien lui dire. Mais quand on veut coder comme un cochon, on peut

  13. #13
    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
    Toi, je sais que tu le sais. Mais je ne voudrais pas que d'autres, moins expérimentés, se figurent que puisque c'est possible, c'est une bonne idée.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  14. #14
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Bon,

    A force de chercher je me suis rendu compte qu'un objet (que l'on va appelé oConteneur) était instancié lors de l'ouverture de l'appli et l'instance de cet objet était le même lors de l'ouverture des articles. Résultat l'objet grossissait jusqu'à atteindre la limite en mémoire. Voila pourquoi le garbage collector ne pouvait supprimer cet objet. Maintenant pour chaque nouvel objet article créé, je crée une nouvelle instance de l'objet oConteneur. Et miracle le garbage collector fait son boulot.

    Voila merci à tous votre aide

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

Discussions similaires

  1. Gestion du cache d'un ResulSet
    Par skunkies dans le forum JDBC
    Réponses: 1
    Dernier message: 30/10/2006, 18h12
  2. Gestion de Mémoire Java
    Par lebulls dans le forum Langage
    Réponses: 5
    Dernier message: 18/07/2006, 10h35
  3. [Sécurité] Gestion du cache / cookies
    Par dug dans le forum Langage
    Réponses: 4
    Dernier message: 25/01/2006, 21h17
  4. [applet] gestion des versions Java
    Par bigVinz dans le forum Applets
    Réponses: 1
    Dernier message: 09/12/2005, 15h06
  5. [Xml][Memoire] gestion du cache
    Par tatou42 dans le forum Format d'échange (XML, JSON...)
    Réponses: 11
    Dernier message: 21/09/2005, 17h48

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