En évitant, trouver et supprimer les fuites de mémoire dans le Cacao
De la mémoire (et de ressources) des fuites se produisent. Comment vous assurez-vous qu'ils ne le font pas?
Quels conseils & techniques de proposeriez-vous pour aider à éviter de créer des fuites de mémoire en premier lieu?
Une fois que vous avez une application qui fuit, comment avez-vous retracer la source de fuites?
(Oh, et merci d'éviter le "il suffit d'utiliser GC" réponse. Jusqu'à ce que l'iPhone prend en charge GC ce n'est pas une réponse valable, et même alors, - il est possible de fuite de ressources et de mémoire sur GC)
Vous devez vous connecter pour publier un commentaire.
Dans XCode 4.5, utiliser le construit en Analyseur Statique.
Dans les versions de XCode avant 3.3, vous pourriez avoir à télécharger l'analyseur statique. Ces liens vous montrer comment:
Utiliser la LLVM/Clang Analyseur Statique
Pour éviter de créer des fuites de mémoire en premier lieu, l'utilisation de la Clang Analyseur Statique à -- sans surprise -- analyse de votre C et le code Objective-C (pas C++ encore) sur Mac OS X 10.5. Il est trivial à installer et à utiliser:
cd
dans votre répertoire de projet.scan-build -k -V xcodebuild
.(Il y a quelques contraintes supplémentaires, etc., en particulier, vous devez analyser un projet dans son "Debug" configuration -- voir http://clang.llvm.org/StaticAnalysisUsage.html pour plus de détails -- mais c'est plus ou moins ce qui se résume à.)
L'analyseur, puis produit un ensemble de pages web qui montre probablement la gestion de la mémoire et d'autres problèmes de base que le compilateur est pas en mesure de détecter.
Si votre projet ne cible bureau de Mac OS X, il y a une couple d'autres détails:
(C'est en grande partie la même réponse que pour cette question.)
Ne pas overthink de gestion de la mémoire
Pour quelque raison, de nombreux développeurs (surtout au début) de faire la gestion de la mémoire plus difficile pour eux que jamais besoin de l'être, souvent par avoir à y penser le problème ou d'imaginer qu'il soit plus compliqué qu'il ne l'est.
La règles fondamentales sont très simples. Vous devriez vous concentrer seulement sur les suivent. Ne vous inquiétez pas de ce que les autres objets pourrait faire, ou ce que l'conserver le comte est de votre objet. La confiance que tout le monde respecte le contrat et il sera tout Juste Travail.
En particulier, je vais réitérer le point sur de ne pas se soucier de conserver décompte de vos objets. L'conserver le comte lui-même peut être trompeur pour diverses raisons. Si vous trouvez vous-même l'enregistrement de l'conserver le comte d'un objet, vous êtes presque certainement la tête dans le mauvais chemin. Recul et demandez-vous, êtes-vous en suivant les règles fondamentales?
Toujours utiliser des méthodes accesseur; déclarer les accesseurs en utilisant les propriétés
Vous rendre la vie beaucoup plus simple pour vous-même si vous de toujours utiliser des méthodes accesseur pour affecter des valeurs à des variables d'instance (sauf dans
init*
etdealloc
méthodes). Outre le fait de garantir que tous les effets secondaires (tels que KVO des notifications de changement) sont correctement déclenché, il est beaucoup moins probable que vous allez souffrir un copier-coller ou de quelque autre erreur de logique que si vous saupoudrez votre code avecretain
s etrelease
s.Lors de la déclaration d'accesseurs, vous devez toujours utiliser le Objective-C 2 propriétés fonctionnalité. Les déclarations de propriété de rendre la gestion de la mémoire sémantique de la accesseurs explicite. Ils fournissent également un moyen facile pour vous à la croix-vérifiez auprès de votre
dealloc
méthode pour vous assurer que vous avez libéré de toutes les propriétés que vous avez déclaré commeretain
oucopy
.Les Instruments de Fuites outil est très bon à trouver une certaine classe de fuite de mémoire. Utilisez simplement Commencer avec un Outil de Performance" /"Fuites" dans le menu pour exécuter automatiquement votre application grâce à cet outil. Fonctionne pour Mac OS X et iPhone (simulateur ou périphérique).
Les Fuites outil vous aide à trouver les sources de fuites, mais n'aide pas tellement suivi de la où la fuite de mémoire est conservée.
Suivre les règles de conservation et de remise à l'eau (ou utilisez la Collecte des Ordures). Ils sont résumées ici.
Utiliser des Instruments pour traquer les fuites. Vous pouvez exécuter une application en vertu des Instruments en utilisant Build > Démarrer Avec la Performance de l'Outil dans Xcode.
Je me souviens à l'aide d'un outil par Omni un moment en arrière, lorsque j'étais en train de suivre les quelques fuites de mémoire qui permettrait d'afficher toutes les conserver/presse/autorelease appels sur un objet. Je pense il a montré des traces de pile pour l'allocation ainsi que tous les conserve et les rejets sur l'objet.
http://www.omnigroup.com/developer/omniobjectmeter/
Tout d'abord, il est extrêmement important que votre utilisation de [ ] et { } les accolades et les crochets correspondent à la norme universelle. OK, juste de la rigolade.
Lorsque l'on regarde les fuites, vous pouvez supposer que la fuite est due à un problème dans ton code, mais ce n'est pas à 100% de la faute. Dans certains cas, il peut y avoir quelque chose qui se produit Apple (gasp!) le code qui est en faute. Et il peut être quelque chose qui est difficile à trouver, car il n'apparaît pas que le cacao objets alloués. J'ai signalé la fuite des bugs à Apple dans le passé.
Fuites sont parfois difficiles à trouver parce que les indices que vous trouverez (par exemple, des centaines de chaînes de fuite) peut se produire non pas parce que ces objets directement responsable pour les chaînes de caractères sont des fuites, mais parce que quelque chose est une fuite que objet. Souvent, vous avez à creuser à travers les feuilles et les branches d'une fuite d'un arbre afin de trouver la "racine" du problème.
De prévention: l'Une de mes principales règles est vraiment, vraiment, vraiment ne plus jamais l'allocation d'un objet sans autoreleasing il y droite sur place. N'importe où que vous alloc/initialisation d'un objet, puis relâchez-il plus tard dans le bloc de code est une occasion pour vous de faire une erreur. Soit vous oubliez de le libérer, ou vous lancer une exception, de sorte que la libération n'est jamais appelée, ou vous mettez un "retour" déclaration pour le début de la sortie de quelque part dans la méthode (chose que j'essaie d'éviter aussi).
Vous pouvez construire la bêta port de Valgrind à partir d'ici: http://www.sealiesoftware.com/valgrind/
Il est beaucoup plus utile que n'importe quelle analyse statique, mais qui n'ont rien de spécial de Cacao encore, que je sache.
Évidemment, vous devez comprendre la gestion de mémoire de base des concepts pour commencer. Mais en termes de traquer les fuites, je recommande fortement la lecture de ce tutoriel sur l'utilisation de l'Fuites de mode dans les Instruments.