Comment identifier des cycles de référence forts dans Swift?

existe-t-il un outil ou une méthode pour localiser les cycles de référence forts dans mon code SWIFT?

un cycle de référence fort est lorsque deux instances de classes se réfèrent l'une à l'autre sans les sécurités appropriées (weak/unowned) empêchant ainsi le collecteur d'ordures de les éliminer une fois que toutes les variables que j'ai créées ont cessé de faire référence à ces objets.

17
demandé sur Itay Moav -Malimovka 2015-08-28 04:55:25

5 réponses

vous pouvez ajouter des fonctions de deinit à vos classes qui seront appelées lorsque vos objets seront désalloués.

si deinit n'est pas appelé, pendant que votre application est en cours d'exécution, vous pouvez appuyer sur le bouton Debug Memory Graph (Encerclé ci-dessous) et inspecter ce qui a une référence à quoi.

Debug Memory Graph Button

Utilisez les menus déroulants en haut du volet du milieu pour basculer entre les classes et les instances de classes.

Si quelque chose est obtenir attribué encore et encore sans obtenir libéré vous devriez voir des instances multiples, et vous devriez être en mesure de voir via le graphique directionnel si l'un de ses enfants tient une référence forte à son parent.

23
répondu texuf 2017-03-30 19:06:12

la méthode pour trouver des cycles de référence forts est la même dans Swift que dans L'objectif-C.

vous exécutez L'application à partir de Xcode, exercez l'application suffisamment pour manifester le cycle, puis appuyez sur le bouton" debug memory graph" (debug memory graph). Vous pouvez ensuite sélectionner un objet non publié dans le panneau à gauche et il vous montrera le graphe de mémoire, souvent qui peut clairement forte référence cycles:

debug memory graph

parfois les cycles de mémoire ne sont pas aussi évidents que cela, mais vous pouvez au moins voir quel objet garde une référence forte à l'objet en question. Si nécessaire, vous pouvez alors suivre en arrière et identifier ce qui garde une référence forte à cela, et ainsi de suite.

parfois, savoir quel type d'objet garde la référence forte est insuffisant, et vous voulez vraiment savoir où dans votre code que fort la référence a été établie. L'option "malloc stack", comme indiqué danshttps://stackoverflow.com/a/30993476/1271826, peut être utilisé pour identifier ce qu'était la pile d'appels lorsque cette référence forte a été établie (vous permettant souvent d'identifier la ligne de code précise où ces références fortes ont été établies). Pour plus d'informations, voir la vidéo de la WWDC 2016 débogage visuel avec Xcode.

vous pouvez également utiliser des Instruments pour identifier les objets qui fuient. Il suffit d'exécuter le app à l'aide d'instruments avec L'outil Allocations, à plusieurs reprises (pas seulement une ou deux fois) retourner l'application à un certain état stable et si la mémoire continue de monter, alors vous avez probablement un cycle de référence solide. Vous pouvez utiliser L'outil Allocations pour identifier quels types d'objets ne sont pas libérés, utilisez la fonction "record reference count" pour identifier précisément où ces références solides ont été établies, etc.

voir la vidéo de la WWDC 2013 Réparer La Mémoire et de la WWDC 2012 vidéo performance de L'application iOS: Memory pour les introductions à l'identification et la résolution des problèmes de mémoire. Les techniques de base proposées ici sont encore applicables aujourd'hui (bien que L'interface utilisateur des outils D'Instruments ait un peu changé ... si vous voulez une introduction à L'interface utilisateur légèrement modifiée, voir la vidéo de la WWDC 2014 améliorer votre application avec des Instruments).

à part, "collecte des ordures" fait référence à un système de mémoire très différent et n'est pas applicable ici.

16
répondu Rob 2018-03-06 17:12:18

utilisez des instruments pour vérifier les fuites et les pertes de mémoire. Utiliser Mark Generation (Heapshot) dans L'instrument de répartition des Instruments.

Pour comment utiliser Heapshot à trouver de la mémoire creap, voir: blog bbum

fondamentalement, la méthode consiste à lancer Instruments attribute tool, prendre un coup de massue, exécuter une itération de votre code et prendre un autre coup de massue en répétant 3 ou 4 fois. Cela indiquera la mémoire qui est allouée et non libérée pendant le itération.

pour calculer les résultats divulguent pour voir les allocations individuelles.

Si vous avez besoin de voir où les conserve, les rejets et les autoreleases se produire pour un objet l'utilisation d'instruments:

Exécuter dans les instruments, les Allocations ensemble "Enregistrer le nombre de références" (Pour Xcode 5 et inférieur, vous devez arrêter l'enregistrement pour régler l'option). Faire fonctionner l'application, arrêter l'enregistrement, forer et vous serez en mesure de voir où tous les conserve, sorties et autoreleases produire.

1
répondu zaph 2015-08-28 02:07:18

l'approche très simple est de mettre une empreinte dans le désinitialiseur

deinit {
   print("<yourviewcontroller> destroyed.")
}

assurez-vous que vous voyez cette ligne se imprimée sur la console. mettez deinit dans tous vos contrôleurs de vue. dans le cas où si vous n'étiez pas en mesure de voir pour particulier viewcontroller, est un cycle de référence.les causes possibles sont le délégué étant fort,les fermetures capturant le soi,les minuteries Non invaidées, etc.

1
répondu Prabhu.Somasundaram 2015-08-28 09:28:24

Vous pouvez utiliser des Instruments pour le faire. Comme dernier paragraphe de cet article états:

une fois les Instruments ouverts, vous devriez démarrer votre application et effectuer quelques interactions, spécialement dans les zones ou les contrôleurs de vue que vous voulez tester. Toute fuite détectée apparaîtra comme une ligne rouge dans la section" fuites". La vue de l'assistant inclut une zone où les Instruments vous montreront la trace de la cheminée impliquée dans la fuite, vous donnant un aperçu de l'endroit où le problème pourrait être et même vous permettre de naviguer directement vers le code incriminé.

0
répondu pxlshpr 2015-08-28 02:02:51