6

I have a static singleton class that extends my User object:

public class TestSingleton extends User{

    private static TestSingleton singletonInstance;

    private TestSingleton() {
    }

    public static TestSingleton getObj() {
        if (singletonInstance == null) {
            singletonInstance = new TestSingleton();
        }
        return singletonInstance;
    }
}

The purpose of the singleton is to avoid create new instance any time i want to use my User object in different activities:

TestSingleton test = new TestSingleton();
test.doSomthing();

And to write it on one line and create instance only one time in my app life cycle:

TestSingleton.getObj().doSomthing();

My question is:

Is this use of static Singleton create memory leak and hold reference to any activity I use the singleton?

Is it safe to use? or there is a better solution?

user3616871
  • 61
  • 1
  • 2
  • Are you sure it _is_ creating a leak or are you asking us if it will? As far as I can see, it won't. Except if `User` holds references to some context for example. – Fildor Nov 12 '14 at 08:47
  • 1
    Note that your singleton isn't thread-safe at the moment, mind you. – Jon Skeet Nov 12 '14 at 08:47
  • Could you accomplish what you need with an `enum`? – Elliott Frisch Nov 12 '14 at 08:48
  • An `Activity` has a reference to your singleton and not the other way around. This means that the singleton won't hold a reference to any `Activity`, but the singleton is only destroyed when all activities that holding a reference to your singleton are destroyed – 0xDEADC0DE Nov 12 '14 at 08:48
  • Fildor - yes i am asking, and the User is just a java class and it's methods doesn't get any context or activity parameters. – user3616871 Nov 12 '14 at 08:52
  • Jon - what do you mean by thread-safe? can you expend about it? – user3616871 Nov 12 '14 at 08:53
  • @user3616871 About thread-safety see blackbelt's answer. It means that two calls to getObj() could happen at the same time leading to two Instances being created. – Fildor Nov 12 '14 at 08:57

4 Answers4

1

Is this use of static Singleton create memory leak and hold reference to any activity I use the singleton?

it won't in the 99.9% of cases,

Is it safe to use?

That depends on what you mean by safe. Your implementation it is not thread safe, for instance. if you call getObj() from two different threads can happen that you instantiate TestSingleton twice.

 or there is a better solution?

There is an implementation of the Singleton pattern that makes use of the Enum. You can find an example on Effective Java

Blackbelt
  • 156,034
  • 29
  • 297
  • 305
  • There is also an implementation of Singleton that is Early. No memory leaks are caused but singletonInstance is instantiated whether it is used or otherwise. https://androidarticlesblog.wordpress.com/2017/07/26/why-lazy-initialisation-of-singleton-is-good/ – veritas Dec 11 '20 at 14:05
0
A memory leak may happen when an object is stored in memory but cannot be accessed by the running code

for a singleton,there is only one object created. And it is only created, when first used. There is no memory leak possible. Only if you want to use it multithreaded, you have to synchronize the instance (), so that the object is only once created.

and 99.99% sure that there won't be any memory leak

Sam
  • 4,046
  • 8
  • 31
  • 47
0

Yes, singletons may cause memory leaks, please read this post: https://stackoverflow.com/a/13891253/1028256

In Android lifecycle activities may be re-created, and it may happen that your singleton keeps a reference to an old activity instance, thus preventing it from being garbage-collected. It means that if you keep such references, you should nullify them in the singleton, on Activity.onDestroy()

FYI the singleton may be destroyed too, when the app is destroyed, so you can't rely on it.

Probably you need to consider keeping data persistently in app storage, or in Application object.

Community
  • 1
  • 1
Mixaz
  • 4,068
  • 1
  • 29
  • 55
  • To quote the post you're linking in your answer "For this reason, the keyword static itself may cause memory leaks, if it references `Activity` objects, so you should be very careful when using it." You can easily work around this by using the Application context instead. – Nicolás Carrasco-Stevenson Nov 03 '16 at 18:35
-1

If you need only one instance of User then you do not need to extend it. What you did in TestSingleton just do it in User class.

For example:

public class User{

private static User singletonInstance;

private User() {
}

public static User getObj() {
    if (singletonInstance == null) {
        singletonInstance = new User();
    }
    return singletonInstance;
}
}

UPDATE:

for thread safety use

public synchronized static User getObj() {
    if (singletonInstance == null) {
        singletonInstance = new User();
    }
    return singletonInstance;
}

I think in this approach you don't need to think about memory leak.

Sayem
  • 4,891
  • 3
  • 28
  • 43
  • The thing is that my User object is a part of source folder that contains multiple objects that I have a singleton for like the User object and it's in git from the server, so i want to avoid change the classes in any pull. can i use the synchronized in my singleton class and it will get the same effect? – user3616871 Nov 12 '14 at 09:01
  • yes you can & that will get same effect & your code will be more reliable. Actually use of "synchronized" is like best practice & it will guarantee 100% that you will never get more that one instance. – Sayem Nov 12 '14 at 09:03