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

Android Discussion :

Fuite mémoire - dalvikvm-heap


Sujet :

Android

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 89
    Par défaut Fuite mémoire - dalvikvm-heap
    Bonjour,

    lors du chargement d'une image, après plusieurs lancements de la même application, l'application crashe avec comme erreur : "Java.lang.OutOfMemoryError".

    J'ai cru comprendre que les images n'étaient pas chargées au même endroit que les autres ressources du code, mais je ne comprends pas comment pallier le problème.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public void deinitPicture()
    {
      _referencePicture.destroyDrawingCache(); // ne marche pas, la memory heap
                                               // grandit quand meme a chaque nouvelle ouverture/fermeture de l'application
      _referencePicture = null; // pas utile parce que fait par la VM ?
    }
    Merci de vos réponses

  2. #2
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Bonjour,

    Avant de se lancer dans du code d'optimisation (qui ne fera que décaler le problème et non le résoudre), il faut trouver d'ou vient le memory-leak...
    Et là on n'a pas beaucoup de code pour le deviner...
    Ce qu'il faut savoir c'est qu'une application n'est pas quittée de suite quand la dernière activité est fermée... donc toutes les statiques, tous les threads peuvent créer des memory-leaks inattendus si il ne sont pas bien gérés... Le plus "classique" des memory leak, est l'utilisation d'un context en statiques..

    Le GC de dalvik tourne sensiblement comme les autres GC
    http://dubroy.com/blog/google-io-mem...-android-apps/

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 89
    Par défaut
    Bonjour,
    J'ai trouvé un moyen de 'détruire' l'image, mais je ne suis pas certain que ce soit le bon.
    Au final, l'application ne plante plus en tout cas :

    je vous donne ma solution :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public void deinitPicture()
    {
      _referencePicture.setImageResource(0);
      // au lieu de _referencePicture.destroyDrawingCache
    }
    et le memory leak vient de l'initialisation/désinitialisation de l'image. En gros, ça buggait juste après initPicture() qui fait juste un _referencePicture.setImageResource(R.drawable.XXXX);
    Le problème venait du fait que en quittant l'appli, l'image n'était pas détruite, j'ai donc résolu avec le SetimageResource(0) lorsque je quitte l'appli, mais je pense qu'il existe d'autres moyens (destroyDrawingCache reste mystérieux pour moi, je pensais justement que c'était ce qu'il me fallait, mais je m'en sors autrement ).
    A savoir, je n'ai plus de fuite de mémoire avec l'appel à setImageResource(0).

    Merci tout de même

  4. #4
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Je continue de penser qu'il y a toujours un memory-leak....

    Une image (j'imagine de type "Bitmap") est un "holder" vers un tableau de byte (byte[])... Ce tableau peut être désalloué à tout moment en appelant Bitmap.recycle(), mais bien entendu, l'objet Bitmap ne peut plus être utilisé par la suite...

    Le GC s'occupe de ça tout seul comme un grand si il n'y a plus de référence à la Bitmap... donc si le faire à la main est utile quand on travaille avec une dizaine de grosses bitmap, il ne servira à rien pour un problème de memory-leak... pour la bonne raison est que ce tableau de byte[] n'est référencé *que* par Bitmap donc même si on appelle "recycle", on va continuer de leaker l'objet "Bitmap", et c'est *ca* qu'il faut corriger... d'autant qu'en général, ce n'est pas l'objet "Bitmap" qui est leaké, mais la vue (et donc tout le contexte avec l'activité). Et avec aussi peu de code, il est difficile d'aider....

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 89
    Par défaut
    Argh ui en effet, j'ai encore une fuite de mémoire (Grow Heap (frag case) to 36.368MB) et la fois d'après, j'ai Grow Heap (frag case) to 36.371MB et ça monte de 0.003 MB à chaque lancement de l'application...

    et pour avoir plus de détails d'un point de vue code, c'est en fait une ImageView et non une Bitmap qui bouffe ma mémoire petit à petit.

    Voila l'extrait du LogCat :

    08-17 15:58:05.760: E/AndroidRuntime(28464): java.lang.OutOfMemoryError
    08-17 15:58:05.760: E/AndroidRuntime(28464): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
    08-17 15:58:05.760: E/AndroidRuntime(28464): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:577)
    08-17 15:58:05.760: E/AndroidRuntime(28464): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:445)
    08-17 15:58:05.760: E/AndroidRuntime(28464): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:775)
    08-17 15:58:05.760: E/AndroidRuntime(28464): at android.content.res.Resources.loadDrawable(Resources.java:1968)
    08-17 15:58:05.760: E/AndroidRuntime(28464): at android.content.res.Resources.getDrawable(Resources.java:677)
    08-17 15:58:05.760: E/AndroidRuntime(28464): at android.widget.ImageView.resolveUri(ImageView.java:542)
    08-17 15:58:05.760: E/AndroidRuntime(28464): at android.widget.ImageView.setImageResource(ImageView.java:315)

    (ceci ce fait lorsque je fait un ImageView.setresource(R.id.xx)... Effectivement je ne sais pas d'où ça vient, et le fait de mettre la ressource à zéro a juste permis de réduire significativement la fuite de mémoire à chaque pas.. je ne sais pas comment la supprimer en entier


    Pour encore plus de précision niveau Code, j'ai une Activity qui possède un GUIManager (qui s'occupe de toute l'interface graphique), et c'est dans cette classe que je fais initPicture() et deinitPicture() qui set la bonne ressource à l'image.

  6. #6
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Le OOM arrive pour dire, "c'est trop tard, y a eu trop de leak"....

    Mais il nous faudrait du code pour chercher... par exemple, le GUIManager (???) me semble un bon début...

    Ensuite, c'est simple....
    Lancer 3 fois l'appli
    Faire un memory-dump (dans le DDMS il y a un bouton pour ca).
    Et regarder les objets instanciés à soi (en partant par exemple des ImageView encore instancés, et voir qui les maintient en vie)

    Si MAT est installé dans Eclipse, le dump va automatique l'ouvrir
    Aller directement à l'acceuil, puis histogram
    Et taper dans le champ en dessous de "Class Name" le nom du package
    Et bim, il y aura toutes les instances des classes "à soi"

Discussions similaires

  1. Créer une fuite mémoire (OutOfMemoryError: Java heap space)
    Par spiffou92 dans le forum Débuter avec Java
    Réponses: 12
    Dernier message: 03/02/2015, 13h45
  2. [tomcat][memoire] java.net.URL et fuite mémoire
    Par Seiya dans le forum Tomcat et TomEE
    Réponses: 6
    Dernier message: 09/03/2009, 10h41
  3. Outil de recherche de fuite mémoire
    Par eag35 dans le forum MFC
    Réponses: 4
    Dernier message: 02/02/2005, 12h46
  4. [SWT]SWT et fuite mémoire(ou pas)
    Par menuge dans le forum SWT/JFace
    Réponses: 2
    Dernier message: 22/06/2004, 21h40
  5. [debug] fuites mémoires
    Par tmonjalo dans le forum C
    Réponses: 3
    Dernier message: 28/07/2003, 17h20

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