macos 避免、查找和消除 Cocoa 中的内存泄漏
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/172125/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Avoiding, finding and removing memory leaks in Cocoa
提问by schwa
Memory (and resource) leaks happen. How do you make sure they don't?
内存(和资源)泄漏发生。你如何确保他们没有?
What tips & techniques would you suggest to help avoid creating memory leaks in first place?
您首先会建议哪些技巧和技术来帮助避免产生内存泄漏?
Once you have an application that is leaking how do you track down the source of leaks?
一旦您的应用程序发生泄漏,您如何追踪泄漏源?
(Oh and please avoid the "just use GC" answer. Until the iPhone supports GC this isn't a valid answer, and even then - it is possible to leak resources and memory on GC)
(哦,请避免“只使用 GC”的答案。在 iPhone 支持 GC 之前,这不是一个有效的答案,即使如此 - GC 上可能会泄漏资源和内存)
回答by mmalc
In XCode 4.5, use the built in Static Analyzer.
在 XCode 4.5 中,使用内置的Static Analyzer。
In versions of XCode prior to 3.3, you might have to download the static analyzer. These links show you how:
在 3.3 之前的 XCode 版本中,您可能需要下载静态分析器。这些链接向您展示了如何:
Use the LLVM/Clang Static Analyzer
使用 LLVM/Clang 静态分析器
To avoid creating memory leaks in the first place, use the Clang Static Analyzerto -- unsurprisingly -- analyse your C and Objective-C code (no C++ yet) on Mac OS X 10.5. It's trivial to install and use:
为了首先避免造成内存泄漏,请使用Clang 静态分析器——不出所料——在 Mac OS X 10.5 上分析您的 C 和 Objective-C 代码(还没有 C++)。安装和使用很简单:
- Download the latest version from this page.
- From the command-line,
cd
to your project directory. - Execute
scan-build -k -V xcodebuild
.
- 从此页面下载最新版本。
- 从命令行,
cd
到您的项目目录。 - 执行
scan-build -k -V xcodebuild
。
(There are some additional constraints etc., in particular you should analyze a project in its "Debug" configuration -- see http://clang.llvm.org/StaticAnalysisUsage.htmlfor details -- the but that's more-or-less what it boils down to.)
(还有一些额外的限制等,特别是你应该在它的“调试”配置中分析一个项目——有关详细信息,请参见http://clang.llvm.org/StaticAnalysisUsage.html——但这或多或少它归结为什么。)
The analyser then produces a set of web pages for you that shows likely memory management and other basic problems that the compiler is unable to detect.
然后分析器为您生成一组网页,显示可能的内存管理和编译器无法检测到的其他基本问题。
If your project does not target Mac OS X desktop, there are a couple of other details:
如果您的项目不面向 Mac OS X 桌面,还有一些其他细节:
- Set the Base SDK for All Configurations to an SDK that uses the Mac OS X desktop frameworks...
- Set the Command Line Build to use the Debug configuration.
- 将所有配置的基础 SDK 设置为使用 Mac OS X 桌面框架的 SDK...
- 将命令行构建设置为使用调试配置。
(This is largely the same answer as to this question.)
(这与这个问题的答案大致相同。)
回答by mmalc
Don't overthink memory management
不要过度考虑内存管理
For some reason, many developers (especially early on) make memory management more difficult for themselves than it ever need be, frequently by overthinking the problem or imagining it to be more complicated than it is.
出于某种原因,许多开发人员(尤其是早期的开发人员)使他们自己的内存管理变得比以往任何时候都更加困难,经常是过度考虑问题或想象它比实际情况更复杂。
The fundamental rulesare very simple. You should concentrate just on following those. Don't worry about what other objects might do, or what the retain count is of your object. Trust that everyone else is abiding by the same contract and it will all Just Work.
的基本规则是非常简单的。你应该专注于遵循这些。不要担心其他对象可能会做什么,或者您的对象的保留计数是多少。相信其他人都遵守同一份合同,一切都会正常工作。
In particular, I'll reiterate the point about not worrying about the retain count of your objects. The retain count itself may be misleading for various reasons. If you find yourself logging the retain count of an object, you're almost certainly heading down the wrong path. Step back and ask yourself, are you following the fundamental rules?
特别是,我将重申关于不要担心对象的保留计数的观点。由于各种原因,保留计数本身可能会产生误导。如果您发现自己记录了对象的保留计数,那么您几乎肯定走错了路。退后一步问问自己,您是否遵循基本规则?
回答by mmalc
Always use accessor methods; declare accessors using properties
始终使用访问器方法;使用属性声明访问器
You make life much simpler for yourself if you always use accessor methods to assign values to instance variables (except in init*
and dealloc
methods). Apart from ensuring that any side-effects (such as KVO change notifications) are properly triggered, it makes it much less likely that you'll suffer a copy-and-paste or some other logic error than if you sprinkle your code with retain
s and release
s.
如果您总是使用访问器方法为实例变量赋值(ininit*
和dealloc
方法除外),那么您的生活就会变得更加简单。除了确保正确触发任何副作用(例如KVO 更改通知)之外,与使用retain
s 和release
s。
When declaring accessors, you should always use the Objective-C 2 propertiesfeature. The property declarations make the memory management semantics of the accessors explicit. They also provide an easy way for you to cross-check with your dealloc
method to make sure that you have released all the properties you declared as retain
or copy
.
在声明访问器时,您应该始终使用Objective-C 2 属性功能。属性声明使访问器的内存管理语义明确。它们还为您提供了一种简单的方法来与您的dealloc
方法进行交叉检查,以确保您已发布您声明为retain
or 的所有属性copy
。
回答by schwa
The Instruments Leaks tool is pretty good at finding a certain class of memory leak. Just use "Start with Performance Tool" / "Leaks" menu item to automatically run your application through this tool. Works for Mac OS X and iPhone (simulator or device).
Instruments Leaks 工具非常擅长查找某类内存泄漏。只需使用“Start with Performance Tool”/“Leaks”菜单项即可通过此工具自动运行您的应用程序。适用于 Mac OS X 和 iPhone(模拟器或设备)。
The Leaks tool helps you find sources of leaks, but doesn't help so much tracking down the where the leaked memory is being retained.
泄漏工具可帮助您找到泄漏源,但对追踪泄漏内存的保留位置没有太大帮助。
回答by millenomi
Follow the rules for retaining and releasing (or use Garbage Collection). They're summarized here.
Use Instruments to track down leaks. You can run an application under Instruments by using Build > Start With Performance Tool in Xcode.
遵循保留和释放规则(或使用垃圾收集)。它们总结在这里。
使用仪器追踪泄漏。您可以使用 Xcode 中的 Build > Start With Performance Tool 在 Instruments 下运行应用程序。
回答by Ashley Clark
I remember using a tool by Omni a while back when I was trying to track down some memory leaks that would show all retain/release/autorelease calls on an object. I thinkit showed stack traces for the allocation as well as all retains and releases on the object.
我记得不久前我使用 Omni 的一个工具试图追踪一些内存泄漏,这些泄漏会显示对象上的所有保留/释放/自动释放调用。我认为它显示了分配的堆栈跟踪以及对象上的所有保留和释放。
回答by danwood
First of all, it's vitally important that your use of [ ] and { } brackets and braces match the universal standard. OK, just kiddin'.
首先,至关重要的是您使用的 [ ] 和 { } 括号和大括号符合通用标准。好吧,开玩笑的。
When looking at leaks, you can assume that the leak is due to a problem in your code but that's not 100% of the fault. In some cases, there may be something happening in Apple's (gasp!) code that is at fault. And it may be something that's hard to find, because it doesn't show up as cocoa objects being allocated. I've reported leak bugs to Apple in the past.
在查看泄漏时,您可以假设泄漏是由代码中的问题引起的,但这并不是 100% 的错误。在某些情况下,Apple 的(喘气!)代码中可能发生了一些错误。它可能很难找到,因为它不会显示为正在分配的可可对象。我过去曾向 Apple 报告过泄漏错误。
Leaks are sometimes hard to find because the clues you find (e.g. hundreds of strings leaked) may happen not because those objects directly responsible for the strings are leaking, but because something is leaking thatobject. Often you have to dig through the leaves and branches of a leaking 'tree' in order to find the 'root' of the problem.
有时很难找到泄漏,因为您找到的线索(例如,泄漏的数百个字符串)可能不是因为直接负责字符串的对象泄漏,而是因为某些东西正在泄漏该对象。通常,您必须挖掘漏水“树”的叶子和树枝才能找到问题的“根源”。
Prevention: One of my main rules is to really, really, really avoid ever allocating an object without just autoreleasing it right there on the spot. Anywhere that you alloc/init an object and then release it later on down in the block of code is an opportunity for you to make a mistake. Either you forget to release it, or you throw an exception so that the release never gets called, or you put a 'return' statement for early exit somewhere in the method (something I try to avoid also).
预防:我的主要规则之一是真的,真的,真的避免分配一个对象,而不仅仅是在现场自动释放它。任何你分配/初始化一个对象然后在代码块中释放它的地方都是你犯错误的机会。你要么忘记释放它,要么抛出一个异常以便释放永远不会被调用,或者你在方法的某个地方放置了一个“返回”语句来提前退出(我也试图避免这种情况)。
回答by alex strange
You can build the beta port of Valgrind from here: http://www.sealiesoftware.com/valgrind/
您可以从这里构建 Valgrind 的测试版端口:http: //www.sealiesoftware.com/valgrind/
It's far more useful than any static analysis, but doesn't have any special Cocoa support yet that I know of.
它比任何静态分析都有用得多,但我所知道的还没有任何特殊的 Cocoa 支持。
回答by Eric Brotto
Obviously you need to understand the basic memory management concepts to begin with. But in terms of chasing down leaks, I highly recommend reading this tutorial on using the Leaks mode in Instruments.
显然,您首先需要了解基本的内存管理概念。但在追查泄漏方面,我强烈建议阅读有关在 Instruments 中使用泄漏模式的教程。