43

When would the garbage collector erase an instance of an object that uses Singleton pattern?

Does an object hang around any longer than a regular object?

How can you manually force deletion/garbage collection of an object in Java?

Thanks.

Julio
  • 1,815
  • 7
  • 20
  • 22

4 Answers4

48

There's a static reference to a singleton, so it won't be eligible for garbage collection until the classloader is eligible for garbage collection.

You can't force any object to be garbage collected; you can request that the garbage collector runs with System.gc() but it's only a request.

If you really want to make a "singleton" eligible for garbage collection, you'd probably want to have a method to set the static variable to null (and hope that nothing else had taken a copy of the reference). Obviously the next time anyone asked for an instance, it would need to be recreated... at which point it's not really a singleton, of course.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Any way around this other than not to use the singleton pattern? – Julio Nov 08 '10 at 19:55
  • 1
    @Franco: You haven't really said what you're trying to achieve, which makes it hard to propose solutions. – Jon Skeet Nov 08 '10 at 19:57
  • 1
    RE "hope that nothing else has taken a copy": If something else has a handle and is actively using it, then this prevents the singleton from being GCed, but that's probably a good thing. But then if another request comes in and we create another instance, we now have two instances of the singleton, which is a bit of a paradox. If you free the singleton (with no extra handles lying around) and then create a new one, maybe that violates the idea of a singleton, depends on definitions I guess. – Jay Nov 08 '10 at 20:06
  • @JonSkeet "so it won't be eligible for garbage collection until the classloader is eligible for garbage collection".Pls can you elaborate on "classloader" stuff here. – NitZRobotKoder Dec 02 '13 at 07:50
  • @NitZRobotKoder: What aspect of it? If you haven't heard about classloaders at all, I'd suggest you start with a search - there's lots of information about them on the web. – Jon Skeet Dec 02 '13 at 08:10
10

There are special objects in Java called GC roots. They are always reachable and so are the objects that can be reached from these roots. These GC roots can never be garbage collected and so do the objects that are reachable from these roots. In Java static variables form GC roots.

Singleton class has a static reference to the instantiated singleton object and hence it will never be garbage collected unless ofcourse as Jon Skeet as stated that the context that loaded this class (class loader) is itself eligible for garbage collection in which case that static reference will not longer be a GC root.

Relevant answer here.

I think this was a bug prior to Java 1.2 when singleton instance could be garbage collected if there was no global reference to it but that was fixed in Java 1.2 and only way now it can be eligible for garbage collection is if the class loader that loaded this class was garbage collected.

Community
  • 1
  • 1
Aniket Thakur
  • 66,731
  • 38
  • 279
  • 289
  • Thanks for a very good answer. A bit more curious now - what was the root cause for that bug? Was the static reference not considered as a valid reference prior to Java 1.2? Thank you. – Saurabh Patil Jun 20 '19 at 03:41
6

If you're keeping a static reference to it in your singleton class, then the reference count cannot drop to 0 and therefore it shouldn't ever get collected.

Reese Moore
  • 11,524
  • 3
  • 24
  • 32
  • 5
    Note that Java generally isn't implemented via reference counting. You may well be aware of this, but your answer *sort of* implies there's counting going on. – Jon Skeet Nov 08 '10 at 19:58
  • The conclusion is correct, but Java GCs can't be implemented with reference counting, because they must be able to collect cyclic data structures as well. – Landei Nov 08 '10 at 20:00
  • 2
    @Jon: True, it would be stronger wording to say that there is always a reachable reference to the object and therefore it is never considered garbage. T'was a slip of the tounge/finger ;) – Reese Moore Nov 08 '10 at 20:02
0

static fields can and do get GCed however this doesn't happen in a simple application.

The static fields are referenced by the Class and the Class is referenced by the ClassLoader. The ClassLoader is referenced by every class and every instance of that class.

However in OSGi containers and application servers it is not unusual to drop every reference to an application or library and it's class loader. At this point the class loader and every static field can be GC-ed.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130