Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 如何使用仪器或查看部件确定ARC保留的对象?_Performance_Swift_Assembly_Instruments - Fatal编程技术网

Performance 如何使用仪器或查看部件确定ARC保留的对象?

Performance 如何使用仪器或查看部件确定ARC保留的对象?,performance,swift,assembly,instruments,Performance,Swift,Assembly,Instruments,这个问题不是关于找出谁保留了一个特定的对象,而是查看探查器中显示有过多的保留/释放调用的代码部分,并找出哪些对象负责 我有一个Swift应用程序,在最初移植之后,它90%的时间都花在保留/发布代码上。在进行了大量的重构以避免引用对象之后,我将其降到了25%左右,但剩余的部分很难确定其属性。我可以看到它的一个给定块来自使用探查器的给定代码段,但有时我看不到该代码中任何(据我所知)会导致保留/释放的内容。我花时间查看了两种仪器中的汇编代码(工作时使用并排视图),以及otool-tvV的输出,有时保留

这个问题不是关于找出谁保留了一个特定的对象,而是查看探查器中显示有过多的保留/释放调用的代码部分,并找出哪些对象负责

我有一个Swift应用程序,在最初移植之后,它90%的时间都花在保留/发布代码上。在进行了大量的重构以避免引用对象之后,我将其降到了25%左右,但剩余的部分很难确定其属性。我可以看到它的一个给定块来自使用探查器的给定代码段,但有时我看不到该代码中任何(据我所知)会导致保留/释放的内容。我花时间查看了两种仪器中的汇编代码(工作时使用并排视图),以及
otool-tvV
的输出,有时保留/释放调用与可识别部分的接近程度会给我一个关于发生了什么的提示。我甚至在某些地方插入了伪方法调用,以便更好地处理代码中的位置,并关闭了优化以限制代码重新排序,但在许多情况下,我似乎必须追溯代码以跟踪分支并找出堆栈上的内容,以便理解调用,而我对x86还不够熟悉,不知道这是否可行。(我将在Instruments中添加几个组装视图的屏幕截图和一些otool输出,以供下文参考)

我的问题是-我还可以做些什么来调试/检查/将这些看似过度的保留/释放调用归因于特定代码?我还能在仪器中做些什么来计算这些电话吗?我使用了分配视图并打开了引用计数选项,但它似乎没有给我任何新的信息(我不确定它到底做了什么)。或者,如果我只是更努力地解释程序集,我是否应该能够找出它保留了哪些对象?在这方面我还应该知道其他的工具或技巧吗


编辑:下面罗布关于单步进入大会的信息是我想要的。我还发现,在lib retain/release调用的XCode中设置一个符号断点并将该项记录在堆栈上(使用Rob建议的“p(id)$rdi”)到控制台上,这样做也很有用,这样可以粗略地计算调用的数量,而不是检查每个调用。

您肯定应该关注程序集的输出。我发现有两个视图最有用:Instruments视图和Assembly assistant编辑器。问题是Swift目前不支持Assembly assistant editor(我通常在ObjC中做这种事情),所以我们来处理您的投诉

看起来您已经在使用debug assembly视图了,该视图提供了一些不错的符号,非常有用,因为您可以逐步查看代码,并希望看到它如何映射到程序集。我还发现它很有用,因为它可以提供更多的符号。一旦在一个区域中有足够多的“惟一ish”函数调用,通常可以开始缩小程序集映射回源的方式

我使用的另一个工具是进入retainbridge并查看传递的对象。为此,请在调用
swift\u bridgeObjectRetain
时执行指令步骤(^F7)。此时,您可以调用:

p (id)$rdi
并且它应该至少打印出一些关于所传递内容的类型信息(
$rdi
在x86_64上是正确的,这似乎是您正在使用的)。我并不总能很幸运地获得更多的信息。这取决于里面到底有什么。例如,有时它是一个
连续数组存储
,我碰巧了解到这通常意味着它是一个
NSArray
。我相信更好的LLDB专家可以深入挖掘,但这通常至少能让我在正确的范围内

(顺便说一句,我不知道为什么在跳入
bridgeObjectRetain
之前不能调用
p(id)$rdi
,但它会给我带来奇怪的类型错误。我必须进入函数调用。)


但愿我有更多。Swift工具链还没有赶上ObjC工具链在IMO中跟踪此类东西的位置。

谢谢!我不知道调试程序中的指令步进,这让我有希望弄清楚保留了什么。我认为它
p(id)$rdi
它将$rdi寄存器的内容转换为对象id来打印?您知道这是调用约定的参数吗,还是应该在程序集中看到它?此外,当指令步进时,似乎XCode通常在我点击某些函数之前不会实际显示任何程序集。当我反复点击^F7时,它位于一行源代码上。这正常吗?再次感谢。是的,
(id)
的意思是“假装它是一个对象”
$rdi
来自x86_64调用约定;调试器并不能帮助您了解这一点(当然,对于ARM来说是不同的)。是的,^F7并不总是按照您希望的方式潜水。有时我不得不进行实验,看看哪种步骤组合能满足我的需求。当然,如果您可以处理未优化的代码(调试模式),那就更好了。程序集将更好地映射到源代码。(当然,在调试/发布过程中,某些性能问题是完全不同的,但当您可以通过调试解决时……)