wood burning stoves 2.0*
The moose likes Java in General and the fly likes Wetware failure and Singletons Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Wetware failure and Singletons" Watch "Wetware failure and Singletons" New topic
Author

Wetware failure and Singletons

Tony Smith
Ranch Hand

Joined: Mar 15, 2005
Posts: 77
Sorry, this is moronic, I'm malfunctioning.

I have a class using a stock Singleton design pattern.

Say that I have some method a() which has a loop. Inside the loop, method b() is called. b() uses a singleton. When control returns to a(), what keeps the singleton from being garbage collected? Clearly it's the static variable within the Singleton... but what is the mechanism here? Is it nothing more than, "A static variable in an class gets lobbed into a shared part of the JVM?"

Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24183
    
  34

Originally posted by Tony Smith:
"A static variable in an class gets lobbed into a shared part of the JVM?"


Garbage collection is described in terms of "roots". Objects reachable from any root are not eligible for collection. Stack frames of live threads and static member variables, as well as various kinds of JNI references and internal handles, all count as roots.


[Jess in Action][AskingGoodQuestions]
Tony Smith
Ranch Hand

Joined: Mar 15, 2005
Posts: 77
So if I am running a 'public static void main()' type of program (versus a servlet, etc), the static variable is associated with the thread running main, so when the thread exits, the static memory is garbage collected?
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

Nope. Threads have nothing to do with it. The static variable belongs to the class it is declared in. So as long as the class is loaded, it contains a reference to that singleton object, and therefore the singleton object can not be garbage-collected. And classes, once they are loaded, stay loaded forever. (Actually it's possible to load a class in such a way that it can be garbage-collected, but you haven't done that in your example.)
Tony Smith
Ranch Hand

Joined: Mar 15, 2005
Posts: 77
When I run the program the 2nd time, the Singleton is gone. Is this because I started a new JVM whic blows away everything, or is it because the singleton was tied to my main somehow?

All along I've just accepted that this works, and it occurs to me I don't know how it works!
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078
Originally posted by Tony Smith:
Is this because I started a new JVM whic blows away everything


yes
Tony Smith
Ranch Hand

Joined: Mar 15, 2005
Posts: 77
Continuing my exciting adventure of discovery...

I'm ok with the fact that running a main() creates a JVM and the Singleton will exist as long as the JVM is running.

I created a web app called T1. It has within it index.jsp and a jar. The jar contains a Singleton's class file. The Singleton does nothing but return a value with a post-increment:



index.jsp does nothing but invoke getValue() and display the result.

When I browsed T1/index.jsp and refreshed several times, the jsp displayed the incremented value as expected. I opened a new browser window and repeated the process. The counter was shared between the browsers meaning both were executing code within the same JVM.

Then I created T2 which was identical to T1. I bound it to the same deployment descriptor that T1 used.

When I browsed T1/index.jsp and T2/index.jsp in different browser windows, it was clear each application was using a different instance of the singleton.

So each web application, then, gets a separate JVM? (And yeah, I could probably get that from the J2EE specification... That's next...)
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24183
    
  34

Within a single JVM, static variables are associated with classes -- this I know you understand. What you may not know is that class files are loaded into the JVM and Class objects are created from them by instances of a class named java.lang.ClassLoader. The JVM comes with its own ClassLoader implementation, but you can write your own subclasses to load classes in your own special way.

What you definitely don't know is that by definition, if two different ClassLoader instances both load the same .class file, they create two different Java Class objects, and therefore two different classes. If ClassLoader A and ClassLoader B both load Foo.class in the same JVM, and Foo.class defines a static variable S, then that JVM contains two different variables named "Foo.S", one for each ClassLoader.

The final piece of the puzzle: each Web app is loaded by its own ClassLoader instance, so that different Web apps don't interfere with each other.
Tony Smith
Ranch Hand

Joined: Mar 15, 2005
Posts: 77
...if two different ClassLoader instances both load the same ... Foo.class in the same JVM, and Foo.class defines a static variable S, then that JVM contains two different variables named "Foo.S", one for each ClassLoader.


And of course, now I ask, when I refer to Foo.S, which class reference is used?
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24183
    
  34

Originally posted by Tony Smith:


And of course, now I ask, when I refer to Foo.S, which class reference is used?


Any reference to Foo.S has to appear in some code, yes? Which has to appear in some class, yes? Call this class Bar. When the JVM is working with some class Bar, and it encounters a reference to a class Foo, it asks the classloader that loaded Bar for the Foo class object. That ClassLoader asks its parent classloader, which asks its own parent, and so on, until either Foo is found, or the root classloader fails to find Foo. Then we come back down the chain, each classloader trying to load Foo on its own, until some classloader succeeds. That class Foo is the one that is used.

The short answer is that whatever classloader loaded the class that wants Foo, is the the one that is asked for Foo.
 
Don't get me started about those stupid light bulbs.
 
subject: Wetware failure and Singletons
 
Similar Threads
singleton pattern
GC
Simple but advanced question
GC doubt
Garbage Collection ...