Can any one please explain possible ways to happen memory leaks while using GWT in development mode as well live mode?
I refer the following question
How to resolve a memory leak in GWT?
as found the below link in one of the answers ..
https://developers.google.com/web-toolkit/articles/dom_events_memory_leaks_and_you
They are mostly deal with Widget creations and browser events. is there any other possible block holes to happen memory leaks like while doing RPC's ..using much rendering methods ..etc etc??
The link you listed talked about how GWT avoids the kinds of memory leaks that browsers are known for - cases where nothing anywhere is referencing the dom element or the widget, but the browser still won't free it from memory. The only case you need to be careful for is when you create your own widgets that hold other widgets - in that situation you need to be careful about invoking attach and detach methods on each child. Sticking with known-good containers and panels will totally save you from this, as well as never invoking attach or detach methods directly.
Beyond that, memory leaks are just like every other kind of development - we need to be careful about keeping references of things you aren't using any more. I disagree with some of the answers in the linked question - Java memory leak tools aren't great at helping to track those objects over Dev Mode, since they think about the JVM and Java objects, not Browsers and JavaScript.
Instead, compile with style set to PRETTY, and use a tool like Chrome's Inspector. That can be used to look at objects that are consuming memory, and tell what is holding on to them. The strategy is the same as with any other heap analysis tool (JProfiler, VisualVM, etc). And the standard rules for writing code apply - if you are holding on to an object you don't need, null it out or remove it from the collection that is holding it. Clearly if you still need it, keep it - and instead something higher up should letting go of that.
Related
In trying to get our webapp (written in GWT) set up for automated testing, I've read/heard that using ensureDebugId() to set element id's causes the app to take a performance hit. Of course setting element attributes would cause a small peformance hit for the final application, but does ensureDebugId() really cause noticable differences in performance? Does it do anything else under the hood besides set element id's?
It does no cause any noticeable performance hit in our 100+ screen application.
Do not micro optimize your application before even writing the code.
Turn on the ensureDebugId and Profile your application.
Turn off the ensureDebugId and profile your application.
If you truly find it affecting performance in the intolerable range then take a call.
ensureDebugId will only cause performance issues if you render tons of elements in your UI, I dont think they are going to be noticeable though. If you have such as UI, probably you will notice performance problems due to other causes.
Anyway, any unneeded single thing you remove from you app will improve your app.
I would enable ensureDebugId only for the test environment, so you could have a different compilation profile to test your app with jenkins or whatever continuous-integration SW you were using, and another profile to produce your deliverable product.
This thread in the gwt list could be useful if you have not read yet.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I've yet to use ARC, since the majority of the code in the project I'm working on at the moment was written pre-iOS 5.0.
I was just wondering, does the convenience of not retaining/releasing manually (and presumably more reliable code that comes as a result?) outweigh any 'cost' of using ARC?
What are your experiences of ARC, and would you recommend it?
So:
How much benefit can ARC bring to a project?
Does ARC have a cost like garbage collection in Java?
Have you been using ARC and if so, how have you found it so far?
There is no downside. Use it. Do it today. It is faster than your old code. It is safer than your old code. It is easier than your old code. It is not garbage collection. It has no GC runtime overhead. The compiler inserts retains and releases in all the places you should have anyway. But it's smarter than you and can optimize out the ones that aren't actually needed (just like it can unroll loops, eliminate temporary variables, inline functions, etc.)
OK, now I will tell you about the small downsides:
If you're a long-time ObjC developer, you will twitch for about a week when you see ARC code. You will very quickly get over this.
There are some (very) small complications in bridging to Core Foundation code. There are slightly more complications in dealing with anything that treats an id as a void*. Things like C-arrays of id can take a little more thinking about to do correctly. Fancy handling of ObjC va_args can also cause trouble. Most things involving math on an ObjC pointer is trickier. You shouldn't have much of this in any case.
You cannot put an id in a struct. This is fairly rare, but sometimes it's used to pack data.
If you did not follow correct KVC naming, and you intermix ARC and non-ARC code, you will have memory problems. ARC uses KVC naming to make decisions about memory management. If it's all ARC code, then it doesn't matter because it will do it the same "wrong" on both sides. But if it's mixed ARC/non-ARC then there's a mismatch.
ARC will leak memory during ObjC exception throws. An ObjC exception should be very close in time to the termination of your program. If you're catching a significant number of ObjC exceptions, you're using them incorrectly. This is fixable using -fobjc-arc-exceptions, but it incurs the penalties discussed below:
ARC will not leak memory during ObjC or C++ exception throws in ObjC++ code, but this is at the cost of both time and space performance. This is yet another in a long list of reasons to minimize your use of ObjC++.
ARC will not work at all on iPhoneOS 3 or Mac OS X 10.5 or earlier. (This precludes me from using ARC in many projects.)
__weak pointers do not work correctly on iOS 4 or Mac OS X 10.6, which is a shame, but fairly easy to work around. __weak pointers are great, but they're not the #1 selling point of ARC.
For 95%+ of code out there, ARC is brilliant and there is no reason at all to avoid it (provided you can handle the OS version restrictions). For non-ARC code, you can pass -fno-objc-arc on a file-by-file basis. Xcode unfortunately makes this much harder than it should be to do in practice. You should probably move non-ARC code into a separate xcodeproj to simplify this.
In conclusion, switch to ARC as soon as you can and never look back.
EDIT
I've seen a couple of comments along the lines of "using ARC is no substitute for knowing the Cocoa memory management rules." This is mostly true, but it's important to understand why and why not. First, if all of your code uses ARC, and you violate the Three Magic Words all over the place, you'll still have no problems. Shocking to say, but there you go. ARC might retain some things that you didn't mean it to retain, but it'll release them as well, so it'll never matter. If I were teaching a new class in Cocoa today, I'd probably spend no more than five minutes on the actual memory management rules, and I'd probably only mention the memory management naming rules while discussing KVC naming. With ARC, I believe you could actually become a decent beginning programmer without learning the memory management rules at all.
But you couldn't become a decent intermediate programmer. You need to know the rules in order to bridge correctly with Core Foundation, and every intermediate programmer needs to deal with CF at some point. And you need to know the rules for mixed-ARC/MRC code. And you need to know the rules when you start messing around with void* pointers to id (which you continue to need to perform KVO correctly). And blocks... well, block memory management is just weird.
So my point is that the underlying memory management is still important, but where I used to spend significant time stating and restating the rules for new programmers, with ARC it is becoming a more advanced topic. I'd rather get new developers thinking in terms of object graphs rather than fill their heads with the underlying calls to objc_retain().
Better, more technical answers than mine will come, but here goes:
ARC != garbage collection. There is no run time penalty, it is done at compile time.
ARC also != just auto releasing everything, as you suggest in your comment. Read the docs
It's awesome once you realise how much manual reference management you were doing
Use it!
One drawback - maintaining old, non-arc code suddenly becomes very tedious.
How much benefit can ARC bring to a project?
The benefit is a significant degree of protection from common memory management mistakes. Leaks caused by failing to release an object and crashes due to failing to retain or prematurely releasing an object should be significantly decreased. You still need to understand the reference counted memory model so that you can classify your references as strong or weak, avoid retain cycles, and so on.
How much does garbage collection really 'cost'?
There is no garbage collection in iOS. ARC is similar to GC in that you don't have to manually retain or release objects. It's unlike GC in that there's no garbage collector. The retain/release model still applies, it's just that the compiler inserts the appropriate memory management calls into your code for you at compile time.
Have you been using ARC and if so, how have you found it so far?
It's a little disconcerting if you're used to reference counting, but that's just a matter of getting used to it and learning to trust that the compiler really will do the right thing. It feels like a continuation of the change to properties that came with Objective-C 2.0, which was another big step toward simplifying memory management. Without the manual memory management calls, your code becomes a little shorter and easier to read.
The only issue with ARC is that it's not supported in older versions of iOS, so you need to take that into account before you decide to adopt it.
I think ARC is a great idea. Compared to GC, you can have your cake and eat it too. I tend to believe that MRC imposes an invaluable 'discipline' towards memory management that everyone would benefit from having.
But I also agree that the real issue to be aware of is Object Ownership and Object Graphs (as many have pointed out), and not low-level reference counts per se.
To conclude: ARC is NOT a free pass to be mindless about memory; it is a tool to help humans avoid repetitive tasks, that cause stress and are prone to error, therefore better delegated to a machine (the compiler, in this case).
That said, I'm personally kind of a craftsman and haven't made the transition yet. I just started using Git...
UPDATE: So I migrated my whole game, gl library included, and no problems so far (except with the migration assistant in Xcode 4.2). If you are starting a new project, go for it.
I've used it in a couple of (admittedly small) projects, and I have only good experiences, both performance- and reliability wise.
One minor note of caution is that you need to learn the do:s and don't:s of weak references not to cause any reference loops if you're coding your UI by yourself, the designer tends to do a good job of it automatically if you set up your GUI using it.
The only downside I have encountered is if you use a library with a lot of CoreFoundation functions and data. In MRC you didn't need to worry about using a CFStringRef instead of an NSString*. In ARC, you have to specify how the two interact (basic bridge? release the CoreFoundation object and move it to ARC? Make a Cocoa object as a +1 CoreFoundation retained object?) Also, on OS X, it's only available on 64-bit code (Although I do have a header that works around that…).
I'm somewhat new to Objective-C and while I think I've got a decent grasp of memory management, I'd like to become familiar with the best ways to test this (if possible).
I know of two options: 1) Build and Analyze (from within Xcode) and 2) Instruments.
Are these the best tools for the job? How accurate is the Build and Analyze feature? I've not used Instruments yet, but it looked somewhat complex when I tried to get started.
I realize the best approach might be to study the Objective-C language itself, but I'm looking for supplemental ways to test this.
Thanks for any insights.
I see a lot of people stating that "Instruments can track down leaks [in context of memory management]" and leaving it at that.
So far from the truth; the Leaks analysis is useful, but barely scratches the surface of the awesome optimization opportunities it can reveal.
Can be used for Zombie detection; i.e. to track down the over-release of an object that causes a crash
Can monitor the allocation bandwidth; the # of objects your app creates/deallocates over time. Reducing that is a very effective means of optimizing an app.
Can inspect the exact set of objects live and in memory at any one time; the working set.
Using Heapshot analysis, can show you exactly how your app permanently grows over time.
Can tell you exactly where any given object is retained and/or released, including backtraces.
The static analyser will attempt to find errors in your code by inspecting it without running it. It's really good at spotting times when you accidentally make an allocation error. It'll tell you about things that are unarguably going to cause a problem and occasions when you've stepped outside of normal Objective-C conventions. So don't necessarily be confused if it highlights something you think won't lead to a problem — Objective-C is a combination of rules and conventions and the analyser looks for breaches of both.
Instruments will look for leaked objects at runtime. So it can find only problems that actually occur. So in principle you'd need to go through every single potential usage path in your program to catch everything. It tends to be really useful in practise though. And it's not that complicated to use. Just launch with the leaks instrument, run for a bit, you'll get a graph of when memory is leaked and you can find out what sort of objects are being leaked. You can then ask to be shown where in the source the object was created. Keep in mind that you'll get some secondary leaks (in that, if one object leaks then all the objects it was retaining will also leak).
On the desktop Guard Malloc is also available, though I think it isn't yet on iOS. That causes your program to run a lot more slowly but will cause it to crash immediately upon any memory access error. So that's really helpful because normally things like writing past the end of C arrays or accessing deallocated objects may cause an error but won't necessarily do so, sometimes causing bugs in some part of the code to corrupt structures used by other parts of the code and cause a crash in code that's completely valid.
Yeah the best thing you can do is to learn more about memory management http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/MemoryMgmt/MemoryMgmt.html
Build and Analyze works pretty well for determining some things like if something is never released. It will help you track down alot of problems, but it is by no means perfect.
Instruments will help you track down leaks but it is a little harder to use and track down exactly where things go wrong.
Another helpful tool you can use to track down crashes from memory is to click Run->Stop On Objective C Exceptions. Which will let you go through stack traces of where your application crashes to find out where it goes wrong.
I'm fairly new to Objective-C (come from a Java background) but I was able to get by with the two features you mentioned (Build/Analyze) and Instruments. I think those worked because I got my app approved by Apple and haven't had any customer complaints so far, so at least that's something.
Anyway I found Analyze to be far less helpful than I would have thought. Mostly I found problems by using Allocations and Leaks Instruments.
Analyze didn't find things that I think they could probably check for. An example would be not releasing (or autoreleasing) an object that you alloc/init and then assign to a retained property. You can even search your source for every time you use alloc and then just do a double check to make sure you're doing correct memory management for each case.
Leaks instrument was very helpful, but make sure you put your app through the ringer while its running. Just click on all sorts of stuff, go in and out of screen lots of times, click on things people would never do, etc. You will find the leaks. Then crush them. Very satisfying.
Clang with xcode is another great option. http://clang-analyzer.llvm.org/xcode.html
I know that there are better ways of sharing objects such as distributed objects but my situation is quite difficult. I'm working on two iPhone apps which are running parallely and need to share an object. That object happens to be a CALayer and it needs to be accessible by both applications. Second application adds its own CALayer to the first app's CALayer and does its work there.
The only way I see is using Shared Memory, but I couldn't find any useful examples of doing exactly what I need. Could someone demonstrate pushing the pointer into shared memory, then retrieving it and serializing it back into the CALayer object?
P.S.: I am aware of the AppStore policies and I don't need another lecture regarding them.
From Memory Usage Performance Guidelines:
The functions used to create and
manage shared memory regions are in
the /usr/include/sys/shm.h header
file.
See also mmap(2), shmctl(2), shmget(2), compat(5)
Don't expect to find a lot of examples for this. This isn't something that is used very often these days. It's old school BSD and plain C. It will only work on a jailbroke device. You'd be better off looking under plain Unix or even Linux resources than Apple API specifically.
Private pasteboard with a name that only your apps know. That's shared memory by other name, and you get free change notifications and stuff.
I'm looking to clean all my app's leaks.
As you can see on the picture below, SQLite makes a lot of memory leak.
I do use SQLite through CoreData. The strangest thing is that AdresseBook is making all the libsqlite3 leak and I never use the AdressBook!!!
Do you have an idea?
Thank you :)
Leaks http://img196.imageshack.us/img196/3997/leaks.png
CoreData doesn't produce any known leaks, therefore your app must be triggering this somehow. AddressBook is a relatively ubiquitous framework on the iPhone in that other system frameworks will end up pulling in AB and AB's data.
Thus, there is something in your app that is triggering the use of AB which is then triggering the use of CoreData.
In any case, since you don't use SQLite directly, you should focus your analysis efforts higher in the stacktrace; at the interface between your code and the system frameworks. Looking at that screenshot, there are two suspicious attributes:
Frames 46, 47, and 48 don't have symbols. Are you running a debug build? If not, do so and those frames should be resolved.
There is a bunch of thread related stuff mentioned. Are you absolutely certain you have done your threading correctly? It is quite easy to create leaks in a threaded application.
(There is also the possibility that these "leaks" aren't really leaks, but are false positives. Probably not, but there is a slight chance you are chasing ghosts)
In any case, the best approach to fixing leaks is to focus on the easy leaks first -- the ones you understand -- and see what remains. Many leaks are often the by-product of other leaks.
Can we see the entire trace?
Also I'm guessing you've already run the static analyser? If not you can find it by going to: Build -> Build and Analyse