problèmes avec des autoReleasePool

tabliertablier Membre
09:05 modifié dans API AppKit #1
J'ai un problème de gestion de mémoire, notamment avec les autoReleasePool.
Je dois d'abord explicité l'architecture de mon programme pour bien m'expliquer.
Le Programme comporte 4 objets qui sont déclarés sous IB: contrôle, extraction, texte et generation. Donc ils sont instanciés au lancement et je ne les supprime jamais. Contrôle initialise et retient les variables Mutables générales que les trois autres objets utilisent.
Pour éviter de garder des variables locales inutilement, dans chacun des objets extraction, texte et generation j'ouvre un nouvel autoReleasePool, j'effectue le travail demandé, puis je "drain" et je retourne au contrôle. Cela marche parfaitement sous 10.5.11 et 10.6.8  mais très mal sous 10.7.2 (voir ce post). j'ai finis par supprimer l'utilisation des autoReleasePool dans les objets extraction, texte et generation et merveille, des tas d'erreurs inexplicables ont disparu.

Ma question: le contrôle des autoReleasePool est maintenu dans un stack. Si j'initialise un nouvel autoReleasePool pour un travail particulier, au cours de ce travail ai-je le droit de lire et/ou modifier les variables qui ne sont pas dans l'autoReleasePool courant?

Nota: Je n'arrive pas avec les textes, à  voir pourquoi la construction ci-dessus serait interdites!

Réponses

  • cyranocyrano Membre
    09:05 modifié #2
    Les NSAutoreleasePoll sont vraiment utiles avec les NSThread et cie.

    as tu une programmation parallèle?
    apres mettre un objet dans un AutoreleasePoll, puis le partager est une très mauvaise idée.

    mais peut être que j'ai pas compris la question.

  • zoczoc Membre
    09:05 modifié #3
    dans 1325948081:

    Ma question: le contrôle des autoReleasePool est maintenu dans un stack. Si j'initialise un nouvel autoReleasePool pour un travail particulier, au cours de ce travail ai-je le droit de lire et/ou modifier les variables qui ne sont pas dans l'autoReleasePool courant?

    Bon, déjà  (je sais que ce n'est qu'une question de terminologie, mais bon...), un autorelease pool ne contient pas de variables, mais des objets (ou autrement dit pointeurs sur zone mémoire contenant les variables d'instance).


    Maintenant, pour répondre à  la question, il est évidemment possible d'accéder à  des objets qui ont été enregistrés dans un pool qui ne se trouve pas au sommet de la pile des pools, et heuresement parce que sinon ce serait vraiment une contrainte énorme...


    Par contre, évidemment, il est plus que périlleux d'accéder à  des objets qui ont été enregistrés dans un pool puis a été drainé, sauf à  faire un retain sur lesdits objets avant le drainage (le drainage n'est rien de plus qu'un appel à  release, donc on se protège contre une destruction lors d'un drainage de la même manière qu'on s'en protège lors d'un release).
  • zoczoc Membre
    09:05 modifié #4
    dans 1325951194:

    Les NSAutoreleasePoll sont vraiment utiles avec les NSThread et cie.

    Pas seulement, les pools sont également très utile à  l'intérieur des boucles qui manipulent beaucoup d'objets, afin d'optimiser la libération de la mémoire.

    apres mettre un objet dans un AutoreleasePoll, puis le partager est une très mauvaise idée.

    Pas si un message retain est envoyé à  cet objet.

  • cyranocyrano Membre
    janvier 2012 modifié #5
    dans 1325951411:

    dans 1325951194:

    Les NSAutoreleasePoll sont vraiment utiles avec les NSThread et cie.

    Pas seulement, les pools sont également très utile à  l'intérieur des boucles qui manipulent beaucoup d'objets, afin d'optimiser la libération de la mémoire.


    oui, et encore on peut "faire" sans pool.



    apres mettre un objet dans un AutoreleasePoll, puis le partager est une très mauvaise idée.

    Pas si un message retain est envoyé à  cet objet.



    ce que je respecterais: bien mettre l'objet dans le pool de son "scope".
  • tabliertablier Membre
    09:05 modifié #6
    Bon, effectivement, pas des variables mais des objets. Dans mon cas, essentiellement des NSMutablesString et des NSMutableDictionary. Ces objets sont initialisés et retenus au lancement de l'application.  J'ai des méthodes récursives (ré-entrantes?) qui font appel à  des méthodes récursives et je ne peux savoir à  priori le nombre de fois qu'elles s'appellent elle-même. Je pensais que les autoreleasePools permettraient de revenir au contrôle en ayant purgé la mémoire utilisée.
       
    apres mettre un objet dans un AutoreleasePoll, puis le partager est une très mauvaise idée.

    Pas si un message retain est envoyé à  cet objet.
    Oui, mais changé le contenu d'un NSMutableString avec setString: C'est autorisé?  D'après ce que dit zoc, je suis pratiquement dans le cas ou l'utilisation des autoreleasePools est intéressante. La seule différence est que je crée le Pool avant le premier appel et je "drain" après le dernier retour. Toute la récursivité voit le même pool.
    Et je ne comprends pas pourquoi ça marche sous 10.6.8 et pas sous Lion!
    ce que je respecterais: bien mettre l'objet dans le pool de son "scope".
    Là , il faut que j'aille relire un peu de doc, car je ne saisis pas tout à  fait l'idée!!

  • AliGatorAliGator Membre, Modérateur
    09:05 modifié #7
    Je crois que t te prends la tête pour rien avec les AutoReleasePools.
    Ce truc marche tout seul du moment que, comme tout le reste, tu équilibre la création et le relâchement de l'objet à  des endroits "symétriques" et pas n'importe où.

    Ton problème est plutôt je pense dans ta gestion de la reccursivité, où tu dois sans doute créer des objets, les détruire et les utiliser dans une boucle récursive quand même.

    Activé les NSZombies histoire de voir quels sont les objets fautifs.
    Assures-toi que chaque objet que tu créés ou retain est toujours retain tant que tu en as besoin et l'utilise et ne le release/autorelease que quand tu n'en a plus besoin.
  • tabliertablier Membre
    09:05 modifié #8
    Je crois que t te prends la tête pour rien avec les AutoReleasePools.
    C'est probable!! à  noter que dans la récursivité, tout les objets sont créés avec des constructeurs de facilité(?) donc pas d'alloc, d'init et pas de retain.
    Je vais voir les zombies (on dirait un titre de film d'horreur).
  • DrakenDraken Membre
    janvier 2012 modifié #9
    Un excellent logiciel du Mac AppStore gère efficacement les problèmes de Zombies :

    http://itunes.apple.com/fr/app/plants-vs.-zombies/id410406848?mt=12

  • tabliertablier Membre
    09:05 modifié #10
      >:D  Soyez sympat, demandez à  muqaddar de vous ouvrir une catégorie spécifique jeux  (pourquoi pas?). Pour ma part, je déteste jouer sur ordinateur!
  • DrakenDraken Membre
    09:05 modifié #11
    * se cache derrière un sac de sable *  :o
  • tabliertablier Membre
    09:05 modifié #12
    se cache derrière un sac de sable
    Oh, pas la peine! Estimons que c'est un peu d'humour. Mais mon idée d'une file du forum dédié aux jeux (programmation, utilisation, partie commerciale.....) devrait peut-être vous intéresser. Enfin, c'est à  voir avec muqaddar.
  • DrakenDraken Membre
    janvier 2012 modifié #13
    Il a décliné l'idée quand je lui ai proposé, courant 2010.  :(

  • cyranocyrano Membre
    09:05 modifié #14
    un truc a tester:

    deactive tes autoreleasePools, as tu tjrs les mêmes bugs?
  • tabliertablier Membre
    09:05 modifié #15
    Le bug n'est visible que sous 10.7 et pas sous 10.5 ni sous 10.6.
    Au premier essai, en supprimant les autoreleasePoll cela devient bon sous 10.7 aussi. MAIS cela laisse apparaitre d'autres bugs en des points que je n'atteignais jamais avec les autoRP actifs.
    Je suis en train de reprendre l'ensemble avant de remettre les autoReleasePool.
  • AliGatorAliGator Membre, Modérateur
    09:05 modifié #16
    dans 1326109851:
    MAIS cela laisse apparaitre d'autres bugs en des points que je n'atteignais jamais avec les autoRP actifs.
    Ce qui semble confirmer ce que je supposais plus haut, à  savoir que c'est pas directement lié à  tes AutoReleasePools (à  si tu les mets ou pas, et dans quelle ARP tes objets vont s'enregistrer pour être release plus tard), mais à  ta gestion mémoire de manière général, genre tu release (ou autorelease, ce qui ne fait que retarder le pb) un objet alors que tu l'utilises plus tard par exemple.

    D'où l'intérêt de NSZombie pour qu'il te dise quand ça arrive et quel type d'objet c'est pour que tu voies tout de suite le pb.
Connectez-vous ou Inscrivez-vous pour répondre.