gpt4 book ai didi

objective-c - 理解 iOS 泄漏调用堆栈跟踪

转载 作者:行者123 更新时间:2023-11-28 18:39:20 24 4
gpt4 key购买 nike

当我使用以下命令调用泄漏时,我有以下 malloc 堆栈跟踪:

MallocStackLogging=1 泄漏

泄漏:0x15d3cac0 size=256 区域:DefaultMallocZone_0x7b0a000

Call stack: [thread 0xb0468000]: | thread_start | _pthread_start | __NSThread__main__ | -[NSThread main] | -[AggregatorObjCWorkQueue newThreadMainLoop] | -[NSRunLoop(NSRunLoop) runMode:beforeDate:] | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopRun | __CFRunLoopDoSources0 | __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ | __NSThreadPerformPerform | -[NSObject performSelector:withObject:] | -[AggregatorTask run] | -[ComAppAggregatorApiSystemClientWorkerFactory_$4_$1 run] | -[ComAppAggregatorFrameworkClientSubscriptionSyncer startWithComAppAggregatorApiClient:] | -[ComAppAggregatorSyncClientSyncSubscriptionRegistry addSubscriptionWithComAppAggregatorQueryQueryXML_Subscription:] | -[ComAppAggregatorSyncClientSyncSubscriptionRegistry newSyncAndPostWithComAppAggregatorQueryQueryXML_QueryKey:] | -[ComAppAggregatorSyncClientSyncSubscriptionRegistry writeUpdateWithComAppAggregatorQueryQueryXML_QueryKey:] | -[ComAppAggregatorSyncClientSyncSubscriptionRegistry writeSubscriptions] | -[JavaUtilTreeMap putWithId:withId:] TreeMap.m:371 | -[JavaUtilTreeMap createNodeWithId:withId:] TreeMap.m:634 | -[JavaUtilTreeMap_Node init] TreeMap.m:1463 | -[IOSObjectArray initWithLength:type:] IOSObjectArray.m:42 | calloc | malloc_zone_calloc

有人可以帮我理解这个来自 malloc 的调用堆栈跟踪吗?即分解问题:1.堆栈跟踪是如何排序的?Class1 方法 1 | Class2 方法 2 | Class3方法3:这些是什么意思?

2:对象描述前的正负号是什么意思?-[类方法] | +[类方法]

3:这些中哪一个实际上是泄露的?我无法准确确定堆栈跟踪的哪个对象/部分正在泄漏。

任何指向文档的链接都会很棒!

最佳答案

使用 Leaks instrument(在 Instruments 应用程序中)在其扩展详细信息 Pane 中查看堆栈跟踪要容易得多。

但这里是分析堆栈跟踪的方法。首先,用换行符替换 | 的每个实例:

Call stack: [thread 0xb0468000]: 
thread_start
_pthread_start
__NSThread__main__
-[NSThread main]
-[AggregatorObjCWorkQueue newThreadMainLoop]
-[NSRunLoop(NSRunLoop) runMode:beforeDate:]
CFRunLoopRunInMode
CFRunLoopRunSpecific
__CFRunLoopRun
__CFRunLoopDoSources0
__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
__NSThreadPerformPerform
-[NSObject performSelector:withObject:]
-[AggregatorTask run]
-[ComAppAggregatorApiSystemClientWorkerFactory_$4_$1 run]
-[ComAppAggregatorFrameworkClientSubscriptionSyncer startWithComAppAggregatorApiClient:]
-[ComAppAggregatorSyncClientSyncSubscriptionRegistry addSubscriptionWithComAppAggregatorQueryQueryXML_Subscription:]
-[ComAppAggregatorSyncClientSyncSubscriptionRegistry newSyncAndPostWithComAppAggregatorQueryQueryXML_QueryKey:]
-[ComAppAggregatorSyncClientSyncSubscriptionRegistry writeUpdateWithComAppAggregatorQueryQueryXML_QueryKey:]
-[ComAppAggregatorSyncClientSyncSubscriptionRegistry writeSubscriptions]
-[JavaUtilTreeMap putWithId:withId:] TreeMap.m:371
-[JavaUtilTreeMap createNodeWithId:withId:] TreeMap.m:634
-[JavaUtilTreeMap_Node init] TreeMap.m:1463
-[IOSObjectArray initWithLength:type:] IOSObjectArray.m:42
calloc
malloc_zone_calloc

问题 1:最旧的栈帧在顶部,最年轻的在底部。所以thread_start调用了_pthread_start,后者调用了__NSThread__main__,后者又调用了-[NSThread main],以此类推。

问题2:名为-[NSThread main]的函数是实现了NSThread的实例方法main的函数 类。 Objective-C 编译器可以生成带有您无法在源代码中逐字写出的名称(如 -[NSThread main])的函数。

对于类方法,函数名以+开头,而不是-。所以 NSObject 上的类方法 alloc 是由名为 +[NSObject alloc] 的函数实现的。

问题 3:您发布的堆栈跟踪显示分配泄漏对象时的堆栈跟踪。该堆栈跟踪的任何部分都不一定“实际上是泄漏的部分”。

您需要了解泄漏对象的含义。意思是没有全局变量或局部变量(在栈上)指向泄漏对象,或者指向一个指向泄漏对象的对象,或者指向一个指向泄漏对象的对象等等等等。由于没有从全局变量或局部变量(我们在商业中所说的“根指针”)开始并导致泄漏对象的指针链,因此您的程序无法访问对象,即使它仍然被分配。

那么为什么会泄露呢?因为在从根指针到您的对象的最后一条链被破坏之前,它没有被释放。它被泄露是因为一个应该被调用的函数——释放函数——没有被调用。它应该在分配对象之后的某个时间被调用。由于泄漏工具仅在分配对象时向您显示堆栈跟踪,因此它可能无法为您提供足够的信息来确定丢失的释放应该去哪里。

这让我们回到了 Instruments 应用程序中的 Leaks 工具。 Leaks 工具也无法向您显示您应该释放的确切位置,但它可以向您显示每次对象被保留、释放和自动释放时的堆栈跟踪。这些额外的堆栈跟踪可以帮助您找出对象泄漏的原因。 Instruments 还比 leaks 命令行工具更好地格式化堆栈跟踪。如果您有泄漏对象网络,Instruments 可以图形方式显示该网络,这可能使您更容易理解您的应用泄漏对象的原因。

Apple 发布了 bunch of developer videos ,其中一些向您介绍了仪器。我不记得究竟是哪个或哪些视频谈论泄漏检测,但我知道至少有一个是这样的。从 WWDC 2012 视频开始,然后往回走。

编辑

WWDC 2012 视频“Session 409 - Learning Instruments”讲述了在 35 分钟左右开始使用 Leaks 工具。

WWDC 2011 视频“Session 310 - What's New In Instruments”讨论了从大约 39 分钟开始使用 Leaks 仪器。

它肯定也在其他一些中提到过。

关于objective-c - 理解 iOS 泄漏调用堆栈跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13380623/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com