Problème de release mémoire

GreensourceGreensource Membre
juin 2010 modifié dans API AppKit #1
Bonjour bonjour!
J'ai un problème de mémoire, (dans mon programme bande de pti rigolo!)
C'est un projet sur iPhone mais ce sont des classes communes donc je préfère mettre ça ici.

Donc, j'ai constater avec Instruments qu'une grosse quantité de mémoire était alloué mais beaucoup trop peu était libéré, je vous joint le graphique éloquent.

Donc Instruments me dit que ce sont des NSData qui ce créer sans ce barrer  >:(

Le code incriminé est le suivant:
NSData *data = [NSData dataWithBytes:source->imageData length:source->imageSize];

la variable source, étant de type IplImage*, c'est un type venant de la bibliothèque OpenCV qui fait du traitement d'image.

Mon premier réflexe, Build&Analyse n'a rien donné et après relecture je voit vraiment pas c'est quoi son problème, selon la norme de codage c'est bien un objet autoreleasé qui m'est rendu ici donc je voit pas ce qui cloche  ???

Quelqu'un à  une idée?

ps: Pour info ce code est exécuté dans un thread séparé

ps2: Je vous joint aussi le code de toute la fonction mais idem je l'ai relu plusieurs fois je vois pas d'où ça viens

Réponses

  • AliGatorAliGator Membre, Modérateur
    17:13 modifié #2
    Dans un thread séparé ---> Tu as pensé à  créer un NSAutoreleasePool pour ton thread (puisque pour rappel contrairement au thread principal où l'ARP est créée pour toi, pour les threads séparés c'est à  toi de la créer) ?
  • GreensourceGreensource Membre
    17:13 modifié #3
    Pour être plus précis j'utilise une NSOperation, donc l'autorelease pool est fait automatiquement selon la doc, et je ne reçoit aucun message du genre: "Pas d'autorelease pool créer, les objets seront juste leaké"
  • GreensourceGreensource Membre
    17:13 modifié #4
    Je continu de chercher, toujours avec Instruments, il m'indique avoir trouvé des leaks mais la bibliothèque incriminé est CoreGraphics  ???
    Ca veut dire que ce n'est pas de ma fautes? Je précise que ça n'est pas lié à  mon problème initial, j'ai trouvé cette leak ailleurs dans le code.

    D'ailleurs je constate quelques choses d'étrange, l'outils Leaks ne m'indique pas de fuite mémoire dans la fonction qui pose problème, on dirais plutôt qu'il n'a pas le temps de libéré la mémoire...

    Je précise aussi que la méthode incriminé va être à  appelé à  la suite d'une callback utilisé par le capteur vidéo pour signaler l'arrivé d'une nouvelle image.

    Or comme la callback n'est pas appelé en continu pour moi il y a forcément un moment ou le système peut relâcher la mémoire. Donc je ne comprend pas.
  • zoczoc Membre
    juin 2010 modifié #5
    "Pas le temps de relacher la mémoire" ça n'a aucun sens tant qu'on utilise pas de garbage collector. La mémoire est relachée immédiatement lors du dernier release sur un objet ou lors du drainage de l'autorelease pool...


    Juste une question... ta "structure" OpenCV IplImage, ou plus exactement la mémoire qui est utilisée par OpenCV, elle est bien libérée quelque part ?

  • GreensourceGreensource Membre
    17:13 modifié #6
    Enfin si dans ma tête c'était: "Avoir le temps de relâcher l'autoreleasepool", mais bon il me semble que c'est systématique en fin de cycle donc oui ça n'a pas trop de sens  :D
  • zoczoc Membre
    17:13 modifié #7
    dans 1276766403:

    Enfin si dans ma tête c'était: "Avoir le temps de relâcher l'autoreleasepool", mais bon il me semble que c'est systématique en fin de cycle donc oui ça n'a pas trop de sens  :D

    Oui, c'est systématique à  chaque nouvelle itération de la boucle de messages. Maintenant, effectivement, si ton NSOperation consiste en une boucle, il serait sans doute opportun d'avoir ton propre NSAutoreleasePool dans cette boucle, avec un drainage à  chaque itération...


  • GreensourceGreensource Membre
    17:13 modifié #8
    Nan nan mon NSOperation n'est pas une boucle, c'est juste qu'une NSOperation est créé dès que je reçoit une image du capteur vidéo.

    Pour être plus précis je créer une nouvelle NSOperation, uniquement si ma NSOperationQueue est vide && que je reçoit une nouvelle image.

    J'ai quand même essayer sans trop y croire d'ajouter un NSAutoreleasePool dans la zone incriminé mais ça n'a pas fonctionné.
  • AliGatorAliGator Membre, Modérateur
    17:13 modifié #9
    Es-tu certain que ça vient de ce bout de code en fait, et que ce n'est pas une fausse piste ?
  • GreensourceGreensource Membre
    17:13 modifié #10
    Ce qui me fait dire que ça vient de là  c'est Instruments.
    Quand je run avec Instruments je vois un malloc 508KB qui se met à  augmenter sans qu'il redescende, donc à  priori c'est lui qui pose problème (cf: screen1)
    Ensuite quand je regarde ce que c'est que ce malloc 508KB je vois que ça viens de la méthode uiImageFromIplImage (cf:screen2)
    Et ce qui est à  l'origine du souci serait un NSData (cf:screen2)

    Donc je ne suis pas sur car je ne maitrise pas très bien Instruments, mais ça semble venir de la quand même. D'autant que quand je met le NSData à  nil, je n'ai plus ce souci.
  • zoczoc Membre
    17:13 modifié #11
    Et si c'était plutôt l'objet UIImage que tu créées et que ta fonction retourne qui n'était jamais détruit ?
  • yoannyoann Membre
    17:13 modifié #12
    Profite des vidéo de la WWDC et jette un oe“il sur la session 311 pour Instruments, ça pourra peut être t'aider.
  • GreensourceGreensource Membre
    17:13 modifié #13
    @yoann ok je regarde ça!

    @zoc pourtant l'UIImage que je créer est en autorelease, tout comme le NSData de toute façon. Mais ouais c'est peut-être ça aussi

    C'est vraiment bizarre cette affaire.
  • manu57manu57 Membre
    17:13 modifié #14
    Salut,

    tu n'aurais pas une directive de debug activée ? type nszombie ou bien une directive d'environnement (Malloc*) ? Ces directives peuvent conserver la mémoire desallouée un certain temp. 

    Manu
  • GreensourceGreensource Membre
    17:13 modifié #15
    Je ne sais plus trop où l'on vérifie ça, mais à  priori non puisque je n'en ai pas mis en place dans ce projet.
  • FKDEVFKDEV Membre
    17:13 modifié #16
    dans 1276843940:

    @zoc pourtant l'UIImage que je créer est en autorelease, tout comme le NSData de toute façon. Mais ouais c'est peut-être ça aussi


    Je pense pour ça aussi. Ton NSData reçoit des retain quand tu le transmets via les différentes API que tu utilises pour créer le UIImage.

    Ensuite le UIImage doit recevoir un retain en dehors de la fonction.
    L'allocation est bien dans la fonction mais le problème vient surement d'un retain en dehors de la fonction que tu n'a pas identifié.

    Ce qui est quand même bizarre c'est que tu n'a pas de leaks sur ton UIImage mais uniquement sur les données de l'image.

    Est-ce que tu utilises la propriété CGImage de l'objet UIImage par la suite ?
  • GreensourceGreensource Membre
    17:13 modifié #17
    Par la suite je ne fait qu'un:
    UIImage* output_image = uiImageFromIplImage(cannyImage);<br />UIView* rotateImage = [[UIImageView alloc] initWithImage:output_image];<br />...<br />[rotateImage release];
    

    donc normalement pas de souci de retain en trop, je vais aller checké les retain count.
Connectez-vous ou Inscrivez-vous pour répondre.