Helping the GC in mono droid using mvvmCross - memory-management

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.

Related

Async read approach for large datasets

OK, so Realm (.NET) doesn't support async queries in it's current version.
In case the underlying table for a certain RealmObject contains a lot of records, say in the hundreds of thousands or millions, what is the preferred approach (given the current no async limitation)?
My current options (none tested thus far):
On the UI thread use Realm.GetInstance().All<T> and filter it (and then enumerate the IEnumerable). My assumption is that the UI thread will block waiting for this possible lengthy operation.
Do the previous on a worker thread. The downside would be that all RealmObject's need to be mapped to some auxiliary domain model (or even the same model, but disconnected from Realm) because realm objects cannot be shared/marshaled between threads.
Is there any recommended approach (by the Realm creators, of course)? I'm aware this doesn't completely fit the question model for this site, but so be it.
Realm enumerators are truly lazy and the All<T> is a further special case, so it is certainly fast enough to do on the UI thread.
Even queries are so fast, most of the time we recommend people do them on the UI thread.
To enlarge on my comment on the question, RealmObject subclasses are woven at compile time with the property getters and setters being mapped to call directly through to the C++ core, getting memory-mapped data.
That keeps updates between threads lightning fast, as well as delivering our incredible column-scanning speed. Most cases do not require indexes nor do they need running on separate threads.
If you create a standalone RealmObject subclass eg: new Dog() it has a flag IsManaged==false which means the getter and setter methods still use the backing field, as generated by the compiler.
If you create an object with CreateObject or you take a standalone into the Realm with Realm.Manage then IsManaged==true and the backing field is ignored.

Dealing with NSManagedObjects when using MVVM

I've been struggling with a good answer to this one for a while:
How do you deal with NSManagedObjects as the Model in MVVM?
I've tried a few different approaches:
Retaining a copy of the NSManagedObject on the ViewModel — although this seems a bit dangerous to me, with the potential for threading issues
Unpacking the NSManagedObject into the properties I actually use on the VM via an -initWithModel: method — this would mean I no longer receive any updates to the NSManagedObject after the initial initialisation
Retaining a copy of the NSManagedObject's NSManagedObjectID, and using an NSManagedObjectContext specifically for each ViewModel instance to retrieve and monitor a private NSManagedObject and it's attributes — this seems a bit heavy to do this for every ViewModel instance (and potentially quite fragile)
None of these seem ideal. I have an idea in my head that it might be best to combine passing in an initial NSManagedObject instance via -initWithModel:, but only retaining the NSManagedObjectID, then listening for core data save notifications and weeding out any that don't relate to the retained object ID.
What I would do, and I don't know if this is necessarily the best practice, is pass in the model and then bind properties of the view model to (possibly mapped) properties on the model. That way you get updates through the view model. It does leave a little bit open to threading problems, but you can use deliverOn: to ensure that updates are always delivered on the main scheduler.

javaFX Memory release , javaFX bug?

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

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/

What type of reference does NSNotificationCenter keep for 'observer's & 'object's?

Can anyone clarify/elucidate the situation with respect to -[NSNotificationCenter addObserver:selector:name:object:]?
What types of references are kept by the notification center of the 'observer' and 'object' arguments?
What are the best practices for removing observers from the notification center?
What are the special concerns for multi-threaded applications, especially with respect to the 'object' argument?
What are the differences in behavior of this method in GC and non-GC environments?
Are the any significant differences (from a client perspective) between mobile and desktop environments in this method's behavior?
Also, any pointers to existing articles which cover this would be greatly appreciated. I Googled, but was surprised to find little in-depth discussion of these issues (although maybe I didn't use the right magic keywords).
what types of references are kept by
the notification center of the
'observer' and 'object' arguments?
I believe a weak reference, though that's just from memory (no pun intended).
what are the best practices for
removing observers from the
notification center?
Always remove the registered object from the notification center before they're released. The object's dealloc method is a good place for this if it set up the registration itself, or when you release it if another object is managing the notification subscriptions. Keep this in mind and the above won't matter.
what are the special concerns for
multi-threaded applications,
especially WRT the 'object' argument?
NSNotificationCenter works fine on threads, but if you send a notification from a background thread, the object will receive it on that same thread. Because of this behavior you should use a different approach if you're updating the UI or doing anything else that's not thread safe (or, dispatch the notification from another method on the main thread).
what are the differences in behavior
of this method in GC and non-GC
environments?
I don't remember hearing of anything that you need to worry about, though I haven't used the GC much yet.
are the any significant differences
(from a client perspective) between
mobile and desktop environments in
this method's behavior?
Not that I've heard of, no. When you register your object you can choose to register for all notifications or only notifications from a certain object. If you're using notifications heavily the latter may be a little faster, but always test to be sure.
Also, any pointers to existing
articles which cover this would be
greatly appreciated. I googled, but
was surprised to find little in-depth
discussion of these issues (although
maybe i didn't use the right magic
keywords).
I think it's more because NSNotificationCenter is pretty easy to use, in general. If you're worried about certain cases, don't be afraid to write a quick test app!
Current situation in 2016:
iOS 9 has changed NSNotificationCenter such that it weak references the target object.
That also to say you no longer have to removeObserver in when the object is dealloc.

Resources