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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau 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
    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 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    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
    Nouveau 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
    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.

  4. #4
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    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

  5. #5
    Nouveau 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
    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é ....

  6. #6
    Membre émérite 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
    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.

  7. #7
    Modérateur
    Avatar de kolodz
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2008
    Messages
    2 209
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    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 209
    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.

+ 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