ios 内存泄漏检测
Xcode supports an awesome Instruments tool to help us detect the Memory Leaks & fix them. One downside of this approach is we have to launch the Instruments tool to find the leaks then fix them on Xcode & verify again on Instruments, these procedures take much time to finish, therefore we mostly run the Instruments after developing, sometime we forget :P
Xcode支持强大的Instruments工具,可帮助我们检测并修复内存泄漏。 这种方法的一个缺点是,我们必须启动Instruments工具来查找泄漏,然后将其修复在Xcode上并再次在Instruments上进行验证,这些过程需要花费很多时间才能完成,因此我们在开发之后主要运行Instruments,有时我们会忘记:P
Sometime, we also find some leaks from other scopes (such as third-parties, framework, …) that we don’t really care because other guys are responsible to fix them instead of us. We only care about the leaks come from our codes. It would be great if we can detect the Memory Leaks of our codes in the Runtime then we can fix & test immediately right on the Xcode!
有时,我们还会发现来自其他范围(例如第三方,框架等)的泄漏,我们并不在乎,因为其他人有责任代替他们来修复它们。 我们只在乎泄漏来自我们的代码。 如果我们能够在运行时中检测到代码的内存泄漏,那就太好了,然后我们可以立即在Xcode上修复并测试!
The whole idea is creating a Singleton LeakDetector instance to track the memory allocation of our objects & notify us when they’re leaked.
整个想法是创建一个Singleton LeakDetector实例来跟踪对象的内存分配,并在对象泄漏时通知我们。
In iOS, objects (reference type) are managed by ARC (Automatic Reference Counting) mechanism. If an object’s retain count is 0 then it should be deallocated immediately. If there’re any delays, it means that object is leaked!
在iOS中,对象(引用类型)由ARC(自动引用计数)机制管理。 如果对象的保留计数为0,则应立即将其释放。 如果有任何延迟,则表示该对象已泄漏!
The implementation of core method should call an assert method to notify us which object is leaked. Why assert? Why not precondition or fatal errors? Take a look in the Apple Documentation:
核心方法的实现应调用一个assert方法来通知我们哪个对象被泄漏。 为什么要断言 ? 为什么不先决条件或致命错误 ? 看一下Apple文档:
Use this function for internal sanity checks that are active during testing but do not impact performance of shipping code. To check for invalid usage in Release builds, see
precondition(_:_:file:line:)
使用此功能可进行内部完整性检查,这些检查在测试期间处于活动状态,但不会影响运输代码的性能。 要检查发布版本中的无效用法,请参阅
precondition(_:_:file:line:)
For the safe reason, let our App be forcefully crashed by assert in Debug to let us be aware instead of users in Release!
出于安全原因,让我们的应用在Debug中被assert强制崩溃,让我们知道而不是Release中的用户!
Now, let’s talk about the way to consider an object is leaked (deallocation delay). Our core method will keep a weak reference to given object from the App, after the deallocation expected time is up by a scheduled timer. If the object is not nil then it should be considered as a leak.
现在,让我们谈谈考虑对象泄漏(释放延迟)的方法。 在预定的计时器释放预期的时间之后,我们的核心方法将对应用程序中的给定对象保持弱引用。 如果对象不是nil,则应将其视为泄漏。
By default, most of collection type such as Array, Dictionary, Set, … in Swift will retain a strong reference to its members. We should avoid this by using NSMapTable. It’s a recommendation for you to read this article to understand & get more use cases of this topic.
默认情况下,Swift中的大多数集合类型(例如Array,Dictionary,Set,...)将保留对其成员的强引用。 我们应该使用NSMapTable避免这种情况 。 建议您阅读这篇文章 了解 并获得该主题的更多用例。
The inTime parameter above can be 1 second by default. We should support a cancelable mechanism to let us stop tracking the object, that’s why the LeakDetectionHandle is needed. This is only a core method, we also should support more convenience methods such as enablement & status, …
上面的inTime参数默认情况下可以为1秒。 我们应该支持一种可取消的机制,让我们停止跟踪对象,这就是为什么需要LeakDetectionHandle的原因。 这只是一种核心方法,我们还应该支持更多便捷方法,例如启用和状态,…
We should keep in mind the Memory Leak detection should/must be done in Debug only, do not ship this mechanism to Production to avoid any unexpected behaviours. Therefore, the implementation of LeakDetector can be like this:
我们应该记住,内存泄漏检测应该(必须)仅在Debug中完成,请勿将此机制提供给Production以避免任何意外的行为。 因此, LeakDetector的实现可以是这样的:
Now, our LeakDetector is ready to use. Let’s try to apply to some places:
现在,我们的LeakDetector可以使用了。 让我们尝试将其应用于某些地方:
When a memory leak occurs, Xcode let app crash with a message to tell us which object is a root cause!
当发生内存泄漏时,Xcode让应用程序崩溃并显示一条消息,告诉我们哪个对象是根本原因!
That’s all, I’ve just shared you guys the idea about the interface (protocol) of LeakDetectorType. There’re many ways to implement base on it.
就是这样,我刚刚向大家分享了有关LeakDetectorType接口(协议)的想法 。 有很多方法可以基于此实现。
I already implemented an open-source here: https://github.com/duyquang91/leakdetector
我已经在这里实现了开源: https : //github.com/duyquang91/leakdetector
This idea & the implementations are inspired of Uber RIBs
这个想法和实现受到Uber RIB的启发
Thanks for reading!
谢谢阅读!
翻译自: https://medium.com/ne-digital/memory-leak-detection-in-runtime-on-ios-cb4193f185fb
ios 内存泄漏检测