iOS 内存泄漏,内存图调试器显示没有泄漏但并行 Xcode-Instruments-leaks 显示泄漏

iOS Memory leaks , memory graph debugger shows no leaks but in parallel Xcode-Instruments-leaks shows leaks

在我的项目中 当我开始在内存图调试器中寻找泄漏时,我发现很少并修复了它们,现在使用内存图没有发现泄漏。 Instruments->leaks 的问题,有时显示泄漏,有时不显示,泄漏从一开始就立即出现,如照片中所述,我几乎不明白导致泄漏的原因。如果内存图显示没有泄漏,我可以信任它吗?或者有一种内存图没有捕获到的泄漏。代码如何初始化 mainViewController:

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    self.window = UIWindow()
    
    let controller = MainViewController()
    let navigationController = UINavigationController(rootViewController: controller)
    let rootViewController = navigationController
    self.window?.rootViewController = rootViewController
    self.window?.makeKeyAndVisible()
           
    return true
        
}

在 2013 年的视频中,Fixing Memory Issues), Apple made a distinction between “leaks”, “abandoned memory”, and “cached memory”, discussed below. For more contemporary discussions, see WWDC 2021 video Detect and diagnose memory issues, WWDC 2019 video Getting Started with Instruments, and WWDC 2018 video iOS Memory Deep Dive

  • 泄漏内存是不能再次访问的内存,没有剩余引用的内存,即已被malloc'ed 但从未 free'd.

  • 废弃的内存包括确实有引用但不会再次访问的内存。

  • 缓存内存是可能不会再次使用的内存,保存在内存中以便在应用再次需要时快速检索。

“调试内存图”擅长查找和可视化由强引用循环引起的问题。 “泄漏”工具不会识别这些问题。由于强引用循环等在 Swift 代码中更为普遍,“调试内存图”通常是更有成效的第一道防线。

调试内存问题时,我们较少担心在循环运行应用程序时第一次和第二次迭代之间的内存使用情况,而是关注后续迭代。

总之,“Leaks”工具和“debug memory graph”针对不同的问题,会产生不同的结果。泄漏没有找到强引用循环。同时,“调试内存图”功能在发现传统泄漏方面变得更好。

FWIW,在 Swift 中,强引用循环比传统的 malloc-but-no-free 泄漏更常见。您的 Swift 代码不太可能出现传统泄漏,除非您开始研究缓冲区的手动分配、非托管核心基础 API 等

如果您发现应用内存增长,在担心泄漏之前,请确保这不是上述视频中确定的第三个内存问题,即缓存内存,可能 不再使用,但当设备内存不足时会自动回收。


顺便说一句,偶尔会有报道称 OS 或框架中存在漏洞。如果 (a) 您没有在堆栈跟踪中看到您的目标被引用;或者 (b) 泄漏是无关紧要的,那么我可能建议根本不要太担心它们。在你的情况下,我们谈论的是 384 字节,我不会太担心。