Reputation: 328
If I have code like this:
public class MyActivity extends Activity
{
private SingletonClass singletonInstance;
...
@Override
protected void onCreate(Bundle savedInstanceState)
{
singletonInstance = SingletonClass.getInstance();
}
...
}
My understanding is that the Activity will remain alive because it has a reference to a static instance and therefore will fail to be GC'd. However, it doesn't seem to cause me any problems in my application. Do I not understand GC or is this really leaking memory and I should avoid keeping a reference to my singleton class?
Upvotes: 4
Views: 2534
Reputation: 1244
I've been using LeakCanary from Square to detect memory leaks in my Android app and there is a leak detected on one of my Activity due to a reference held by a static singleton obj.
My Activity as the same structure as in the Q, where the Activity has a reference to a singleton Presenter class but the reference is not static.
public MyActivity extends Activity {
private MyPresenter mPresenter;
...
onCreate() {
mPresenter = MyPresenter.getInstance()
...
}
}
..
public class MyPresenter { // Different class
private static MyPresenter mInstance;
... singleton code ...
}
I read this link and I guess it makes sense. http://www.javaworld.com/article/2071737/core-java/plug-memory-leaks-in-enterprise-java-applications.html
Once the Singleton class is instantiated, it remains in memory for the application's lifetime. The other objects will also have a live reference to it and, as a result, will never be garbage collected.
Recommendation:- Avoid referencing objects from long-lasting objects. If such usage cannot be avoided, use a weak reference, a type of object reference that does not prevent the object from being garbage collected.
Upvotes: 1
Reputation: 3058
Researched about your doubt and I confirm my answer:
It would happen if you declared singletonInstance as static. For your Activity, singletonInstance is just an instance of SingletonClass. Remember that there's no such thing as a "static instance", the instance is just an object of a given class, what makes it static is the way you declare it in your scope. For MyActivity, singletonInstance is not static, even if inside SingletonClass you're referencing to the same object/instance and there it is declared as static.
This way, your Activity can be cleaned up by GC without issues. I have a similar implementation on Android and it involves a Service, have had it running for hundreds of hours without any memory or performance issues...
Regards
Upvotes: 1