javaFX Memory release , javaFX bug? - performance

I found when switch pages frequently in the javaFX sample Ensemble.jar, memory will get higher an higher and can't release. This also happened in my project.
Is that a bug of javaFX? Now our testers are always complaining about this problem.
Are there some good ways to solve this problem? What can we do in "memory release" in javaFX?
To solve this problem,what we've done:
Set the global variables to NULL when we destroyed the javaFX pages.
Decrease the use of "repeated big images" in .css file.
Invoke GC in Platform.runLater(). (This seems a little silly)
But the effect is not so clear, Who can help us?

This is not a bug in JavaFX.
I guess your memory leaks come from the use of listeners on Properties.
JavaFX uses Properties as an implementation of the Observer Pattern. When you add a ChangeListener to a property, you actually add a reference to your listener in the property object. If you don't call the RemoveListener method to remove this reference, your listener won't be garbage collected as long as the property object is not garbage collected itself.
I have no idea of what your code looks like but I can make some assumptions:
Each time you switch pages you instantiate a new controller
Each controller instantiate a listener object and add it to a property object.
When switching pages the previous controller is garbage collected while the property object is not. In the property object, there is a reference to the Listener object and thus the listener object remains in the memory.
The more you switch pages, the more you instantiate listeners that won't be garbage collected, the bigger your memory leak is.
If you add Listeners to Properties, try to call the removeListener method and see if it solves the problem.
Regards,
Cyril

Related

Cocoa: Finding the missing reference for deallocating

I'm almost done with and app and I'm using instruments to analyse it. I'm having a problem with ARC deallocating something, but I don't know what. I run instruments using the allocations tool ,what I'm doing is starting the app at the main view, then I mark a heap, I interact with the app a little and return to the original main view and mark another heap.
I do this several times and as I understand it, there should not be any significant heap growth because I am returning to the exact same place, everything I did in between should have been deallocated, providing no heap growth. However I have significant growth so I dive into the heaps and I find that almost everything on it has a retain count of 1, which leads me to believe that one object or view, etc is not being deallocated because of a mistake I've made and that object is what's holding references to everything else.
What I'm trying to find out is which object is not being deallocated. Instruments is very vague and only offers obscure pointers that do not allow me to trace back the problem.
Please let me know if there is a way for me to trace what is holding a reference that may be keeping the retain count at 1.
Thanks.
My 1st thought are 2 things:
1) You may have a retain cycle: As an example, one object has to a delegate a strong reference. And the delegate has also a strong reference (instead of a weak reference) to the 1st object back. Since both of them "hold" the other one, none of them can be released.
2) You may have a multi-threaded app, one of the threads does not have an autorelease pool assigned (i.e. does not have an #autoreleasepool block), and is creating autorelease objects. This may happen even in a simple getter method that returns an autorelease object. If so, the autorelease object is "put" into an non-existing autorelease pool (which does not give you an error message, since you can send any message to nil), and it is never released.
Maybe one of these cases applies to your problem.

Helping the GC in mono droid using mvvmCross

I am working with mono droid, using the mvvmcross framework provided by slodge. However I am having some memory issues. I am disposing bitmaps in the activities ondestroy methods and I am wondering if it is possible to help the GC collecting unused objects of viewmodels. If you try setting the viewmodel in the activity to null it all goes to hell and it is clearly not the right way to go.
Do you guys have any suggestions to an approach?
Regards
The mvx framework tries to ensure that the activity owns the viewmodel.
So in theory, after your activity has being destroyed, then the gc should be able to collect all of your c# objects - the activity, the views it owns, the view model and the objects it owns.
Where i've seen this this go wrong is where any 'global' or singleton object owns a reference to a view or viewmodel object. For example:
if a view registers itself with a singleton - eg an http image loader - and then that singleton keeps a reference to the view, preventing it from being garbage collected.
if a viewmodel subscribes to an event on a central service (often a singleton) and doesn't unsubscribe from it - then in this situation, the viewmodel can't be garbage collected (and often this also prevents other objects being collected too)
Generally both these types of errors can be solved by performing cleanup actions on activity destroy. However, other approaches are also available - eg for event subscriptions you can try using weak references (this is an approach taken on other platforms too - eg mvvm light's messenger)
From experience, the areas where leaks are most noticeable are around 'big objects' like images - their size helps them become noticeable. However, the real challenge on monodroid is identifying where the leaks are - fixing them is generally comparatively easy.
Sadly, there isn't currently a memory profiler available for droid. If you are cross-compiling to wp7, then certainly for viewmodel objects/leaks you can use its memory profiler. If not, then the way I generally try to solve memory leaks is to amplify them - try writing a sample that rapidly reproduces them - eg by adding large byte[] members to data elements or by rapidly repeating actions. Once you have the leak easily reproduced, then you can try to find the leaks by placing trace statements in finalizers, in event remove handlers, etc.

Cocoa: Object getting autoreleased when it shouldn't

First, I should say I'm using ARC, so retain is not an option. The object's class is of type NSViewController and has two NSTimers as well as several textfields and buttons. The odd thing is that when the two timers are invalidated, it looks like the object is being released. This is a problem because sometimes I just want to pause or restart them, which means I have to invalidate them, but once I do, the reference is lost, and any message to the object will throw a EXC BAD ACCESS.
I'm not very familiar with memory management or ARC but why is the reference lost depending only on the timers? I mean, just because they're invalidated does not mean I don't need the object anymore.
I've tried declaring the timers as instance variables and properties but nothing changed.
What I really need is for the reference not to be retained, even when both timers are invalidated. What am I doing wrong?
NSTimer retains its target, so if it is the only reference to the object it will be deallocated when the timer is invalidated. You'll have to take ownership of your object, preferably by making it a declared strong property.
Edit: Changed "delegate" to "target";
Yes, you'll have to declare a property and (possibly) an instance variable for it.
The release notes give a good example, there are a couple other good intros around. Make sure that you invalidate the timer if your owner class is ever deallocated, otherwise your view controller will hang around.

Win from application gets slow

I have built an application using Visual Studio .NET and it works fine. After the application is used for more than 2-3 hours it starts to get slow and I don't know why. I have used GC.Collect(); to get memory leak problems but now I have the new one.
Does anyone know a solution?
If you really have a memory leak, just calling GC.Collect() will get you nowhere. The GarbageCollector can only collect those objects, that are not referenced from others anymore.
If you do not cleanup your objects properly, the GC will not collect anything.
When handling with memory consumptions, you should strongly consider the following patterns:
Weak Events (MSDN Documentation here)
If you do not unsubscribe from events, the subscribing objects will never be released into the Garbage Collection. GC.Collect() will NOT remove those objects and they will clutter your memory.
Implement the IDisposable interface (MSDN documentation here)
(I strongly suggest to read this ducumentation as I have seen lots of wrong implementations.)
You should always free resources that you used. Call Dispose() on every object that offers it!
The same applies to streams. Always call Close() on every object that offers this.
To make points 2. and 3. easier you can use the using blocks. (MSDN documentation here)
As soon as these code blocks go out of scope they automatically call the appropriate Dispose() or Close() methods on the given object. This is the same, but more convinient, as using a try... finally combination.
Try a memory profiler, such as the ANTS Memory Profiler. First you need to understand what's going on, then you can think about how to fix it.
http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/

Windows Form Closed but not destroyed

In my Windows Form application when I close a form (which is derived from a base form), its FormClosing and FormClosed Events fire but destructor never fires off. It still keeps the memory occupied.
Any ideas on how to destroy the form completely when it is closed?
If it's not destroyed that means the Garbage Collector doesn't think it should be destroyed.
This basically means that you're either:
Holding a reference to the object somewhere
Have the object listening to an event (That's also a kind of reference to the object)
The garbage collector won't free the Form until there are no references to it.
If you have important resources you want to dispose of, make it IDisposable, and use the Dispose method.
Destructors (or more correctly, finalizers - there are no destructors in .NET) are not guaranteed to be executed in .NET - objects may be cleaned up at the whim of the runtime or even never. You cannot rely on your finalizer method ever being called.
If you need to do something when your form is closed, handle the Closed event.
If you need to release an unmanaged resource (e.g. close an open file), add this logic to the Dispose() method.
If you are worried about memory use, do not worry about memory use. The runtime manages memory automatically based on its own logic.
Reference: Garbage Collection (MSDN)

Resources