I wrote a OSX App using ARC, just load a tableview without any cells,the memory is up to 50M+,
I want to know any way to optimize it.
(Can not use release , I can not find any other way)
================================= UPDATE========================================
I created a demo Application , just a blank window, the memory is up to 40M+, sigh
There shouldn't actually be a difference between using ARC or not--think of ARC as adding release calls for you automatically. This answer has an illustration of this point.
Related
Hello I am completely new to Apple development
I used this code in my project
https://github.com/vladinecko/accordion-uitableview/tree/master/AccordionTableView
, project releases the memory itself using autorelease
What made me disable the ARC
Because ARC does not allow the use of autorelease
My question is whether to delete the autorelease from the code
And use ARC or i can not do it and I need to have to release the memory for myself
You could leave the code as-is—you can compile some files using ARC and others not, but that’s going to be messy and hard to maintain.
What I’d recommend doing is running Xcode’s ARC-ifying on the code, to get rid of retain and release and autorelease.
In Xcode 5, look under the “Edit” menu for “Refactor”, and select “Convert to ObjC ARC”.
Apparently AccordionTableView does not use ARC, whereas in your project you are using it.
So you have three options
Switch off ARC only for the separate compilation units, which are from AccordionTableView
Adapt the code snippet from AccordionTableView project with ARC guidelines
Switch your own project to not use ARC
First, being new to Objective-C development you need to learn how memory management works. Google for "Apple memory management" and you should find relevant documents.
Before ARC, people did memory management by hand. With ARC, ARC does it for you. The exact same memory management operations should happen, except that with ARC you have less programmer work, and chances to get it right are better.
You have two choices: Either turn ARC off for individual files. This is done in Xcode / target settings / Build phases / Compile sources by adding -fno-objc-arc to the build settings for individual files where you don't want to use ARC. If you use the same files in different projects, you have to do this in every target.
The other choice is to convert the files to ARC. Let the compiler run, remove offending memory management code, which is mostly retain / release / autorelease. If the code uses CoreFoundation functions, then you really need to understand memory management, just hope it doesn't. Use "Analyze" to let the compiler check very carefully that everything is fine.
I believe I successfully converted by app to ARC using the 'Refactor -> Convert to Objective-C ARC' tool but only one of my project targets has the setting:
And if I create anything using IB it is still generating retain / release / dealloc code?
Also I now have crashes I did not before because of memory use, so I am wondering if my project is in a half converted state that is causing me random memory issues.
How do I get these other targets to use ARC - or make sure they are using ARC?
Manually change the flags to say YES. Also want to check and make sure that none of the files have the compiler flag "-fno-objc-arc" set. (I've run into projects that were half converted this way.)
If you're still running into memory issues, run the Leaks Instrument. Even with ARC, you can still have memory leaks like retain cycles where parent-child relationships retain each other. In such a case, you need to use weak pointers.
Looking at the release notes of OS 10.7, there's some stuff about using Automatic Reference counting (ARC) to make memory management simple. I'm about to embark on a new Cocoa project soon and wondered whether it would be worth using the model (the way I understand it, you can't mix between using ARC and not using it)?
The dilemma seems to be using something new versus using something that could potentially save lots of debugging time later. But is that the case? Has anyone played around with it and found no real-world benefit?
Without a doubt you should use ARC. ARC injects the retain release calls at the most appropriate times, so you may actually see lower average memory use than you would if you didn't use ARC.
I have used ARC and it is immensely powerful. You stop having random crashes and your app just feels more responsive. As they said at WWDC, there is no reason not to use Automatic Reference Counting.
Also, you can use non-ARC files in the same project as ARC files.
I agree with FreeAsInBeer about using ARC. However, it should also be made clear that garbage collection (GC) should not be used. It looks like Apple is henceforth going to focus their efforts ARC, while letting GC die a slow death. This is wonderful because ARC is clearly a far superior technology, whereas GC is slow and extremly buggy.
So yes. Use ARC. Stay away from GC.
I am an experienced C/C++ programmer, and familiar with memory management issues. I've also shipped a couple small iPhone apps in the past. I am attempting to check my latest app for memory leaks, and I can't make any headway, because there are so many of them. Just starting the app and viewing the first screen shows over 12,000 leaks.
I know I've probably overlooked various things, but I was reasonably cautious in writing the code. I made attempts to release everything I alloc'ed in my dealloc method. It is like my app delegate never gets released, because I can see a couple things that are only alloc'ed once, in the app delegate's init method. They are never modified, and are released in the dealloc method.
This app is built around a tab controller, with around 15 views mainly set up using Interface Builder.
Any help would be appreciated.
Instruments of apple is pretty advanced.. it can show you the exact method that originally created the memory leak, I suggest taking a look at those methods and carefully reading your code ,there usually is this line of code in there and you thought OMG how could I be that stupid.
If that doesn't help, try to "Analyze" with xcode, its pretty good at finding errors and leaks in your code and saved my * a couple of times.
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)
In XCode 4.5, use the built in Static Analyzer.
In versions of XCode prior to 3.3, you might have to download the static analyzer. These links show you how:
Use the LLVM/Clang Static Analyzer
To avoid creating memory leaks in the first place, use the Clang Static Analyzer to -- unsurprisingly -- analyse your C and Objective-C code (no C++ yet) on Mac OS X 10.5. It's trivial to install and use:
Download the latest version from this page.
From the command-line, cd to your project directory.
Execute 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.html for details -- the but that's more-or-less what it boils down to.)
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:
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.
(This is largely the same answer as to this question.)
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 rules are 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?
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 retains and releases.
When declaring accessors, you should always use the Objective-C 2 properties feature. 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.
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).
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.
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.
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 think it showed stack traces for the allocation as well as all retains and releases on the object.
http://www.omnigroup.com/developer/omniobjectmeter/
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.
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 that object. 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).
You can build the beta port of Valgrind from here: 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.
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.