Static class garbage collection

Can garbage collector can garbage collect static classes ?.
My doubt is that when you access a static class , that class is loaded through its class loader ( when first time that class is referenced ).
So when did the garbage collector collects this static class ( assume that static class no longer referred ).
Please do more information,
What are the ways to prevent garbage collector for a particular class ( Assume that i m implementing a singleton for my java runtime)
thanks and regards
Renjith.

Can garbage collector can garbage collect static classes ?. Static classes are nothing special in terms of class loading - they are only different in visibility for linking.
Perhaps you mean static members of classes?
My doubt is that when you access a static class ,
that class is loaded through its class loader ( when
first time that class is referenced ). Classes are always loaded through classloaders. Objects of those classes are allocated from the heap, and the object instances refer to the class object.
Objects (either instances, or classes themselves) are garbage collected when they are no longer live (i.e. no live object refers to them). (This is a somewhat recursive definition, and sometimes, you can have cyclic dependencies that make garbage collection tricky, but the GC, while it has to be conservative for correctness, usually gets it right).
So for a static member to be garbage-collected, the class has to be garbage-collected first. The class cannot be GC'ed until all references to it go away (this includes all dynamically allocated objects of that type, and the class loader that loaded that class).
And yes, class loaders can go away, but only if they are created by your program. The system class loader (which is the default classloader you get if you don't create any class loaders of your own) never goes away, so any class loaded from CLASSPATH will never be unloaded.
(As an example, servlet containers - e.g. Tomcat, Weblogic, etc.) allocate one or more classloaders for each webapp. When the webapp is un-deployed, the classloaders are "orphaned", and they, and any classes loaded by them (from the WEB-INF/lib and WEB-INF/classes directories) are unloaded and garbage-collected. (After all the dynamic objects of those classes are GC'ed, of course).
>
So when did the garbage collector collects this
static class ( assume that static class no longer
referred ).
Please do more information,
What are the ways to prevent garbage collector for a
particular class ( Assume that i m implementing a
singleton for my java runtime)
thanks and regards
Renjith.

Similar Messages

  • How can I prevent class garbage collection????

    Hi,
    Is there a way to prevent a class from being garbage collected without using the -noclassgc option? Is there some code I can include in a class that tells the JVM not to garbage collect that particular class?
    Thanks in advance,
    Jacob.

    The code shown below (slightly modified from yours) should work correctly on any 1.0.x throught 1.4 JVM.
    Look at this article for further info: http://www.javaworld.com/javaworld/javatips/jw-javatip52.html
    public class SQLManager extends PoolManager {
        private static SQLManager myself;
        //code.........................
        public static SQLManager getInstance() {
            // This version of a getInstance method suffers from the use of the
            // broken (unreliable) double checked locking idiom.  It should never
            // be used on a system with more than one processor and is ill-advised
            // any other time.  It can  lead to accesses to uninitialized objects.
            // See http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html
            // or http://c2.com/cgi/wiki?DoubleCheckedLockingIsBroken
            // So despite its common appearance in books and pattern repositories,
            // it should not be used.
            if (myself == null) {
                synchronized(SQLManager.class) {
                    if (myself == null)
                        myself = new SQLManager();
            return myself;
        private SQLManager() {
            livethread();
            //code.........................
        void livethread()
            System.out.println("##############################################################");
            System.out.println("###################Live Thread called#########################");
            System.out.println("##############################################################");
            Thread thread = new Thread()
                public void run()
                    // added this code to ensure that run() actually is getting
                    // called
                    System.out.println("##############################################################");
                    System.out.println("#################### Thread Started ##########################");
                    System.out.println("##############################################################");
                    Class myClass = SQLManager.class;
                    while (true)
                        try
                            synchronized (myClass)
                                myClass.wait();
                        catch (InterruptedException ex)
                            System.out.println("##############################################################");
                            System.out.println("###################Thread interrupted#########################");
                            System.out.println("##############################################################");
                        finally
                            System.out.println("##############################################################");
                            System.out.println("################### Something Happened #########################");
                            System.out.println("##############################################################");
                    System.out.println("##############################################################");
                    System.out.println("#################### Thread Dead?? ##########################");
                    System.out.println("##############################################################");
            thread.setDaemon(true);
            System.out.println("##############################################################");
            System.out.println("#################### Starting Thread #########################");
            System.out.println("##############################################################");
            thread.start();
        //code.........................
    }

  • URL class is not being garbage collected

    I have created two instances of the URL class to specify a file location for each image. I use com.symantec.itools.javax.swing.icons.ImageIcon class to display images specified by each URL instance as icons inside a button. The setImageLocation method(URL location) of the ImageIcon class sets the location to be displayed by this icon. The following is the code snippets used to create the ImageIcon instances:
    private URL greenIconURL;
    private URL redIconURL;
    com.symantec.itools.javax.swing.icons.ImageIcon green_icon = new com.symantec.itools.javax.swing.icons.ImageIcon();
    com.symantec.itools.javax.swing.icons.ImageIcon red_icon = new com.symantec.itools.javax.swing.icons.ImageIcon();
    try
    greenIconURL = new java.net.URL
    ("file:./images/greenline.gif");
    green_icon.setImageLocation(greenIconURL);
    catch (java.net.MalformedURLException error) { }
    try
    redIconURL = new java.net.URL
    ("file:./images/redline.gif");
    red_icon.setImageLocation(redIconURL);
    catch (java.net.MalformedURLException error) { }
    I am using JProbe 5.0.1 Memory to determine the loitering objects when I remove the button from the JInternalFrame. I am using Java 1.2.2_08 version. The JProbe Memory Leak Doctor indicates that each URL instance has a reference to an entry in a HashMap table. The reference graph from the root set has a reference to SoftCache to HashMap to HashMap$Entry. To make this URL instance eligible for garbage collection, JProbe Memory Leak Doctor indicates I must remove the entry from the HashMap. How do I get access to this HashMap to remove the entry? If this is a problem with the version of the JDK, please let me know. Thank you in advance for your assistance.

    <root>Statics
    -->sun.misc.SoftCache->java.util.HashMap->java.util.Has
    Map$Entry[]->java.util.HashMap$Entry->java.net.URL
    I do not an instance of HashMap in my class.
    Therefore, the HashMap is either created by URLclass
    or the
    com.symantec.itools.javax.swing.icons.ImageIcon
    class.SoftCache seems to have a normal HashMap inside
    it/* Hash table mapping keys to ValueCells */
    private Map hash;but if that is the HashMap in JProbe
    information then the URL would have to be a key in
    the map - otherwise there'd be another object in the
    chain of class SoftCache.ValueCell
    are you certain that the java.net.URL's in that
    hashmap are your ones?
    out of curiosity - are you certain that the URL's are
    the/a problem (are you getting an OutOfMemoryError?)
    asjfThe button that contains the URL's is the only one on the JInternalFrame. The JProbe Memory Debugger displays the java.net package name, the URL class name, the count (2), and the Count Change (+2). When I remove the button from the JInternalFrame, the aforementioned numbers on the Instance Summary remain the same. The snapshot of the Java Heap reveals that the two instances of the URL class are still there. The Memory Leak Doctor shows the reference graph from the root set:
    <root>Statics->SoftCache->HashMap->HashMap$Entry[]->HashMap$Entry->URL
    When I right click on the arrow between HashMap$Entry[] and HashMap$Entry to remove the reference, I receive the message: "Congratulations this object can be garbage collected..." It appears like private instance of Map in SoftCache is holding a strong reference.
    I am not getting an OutOfMemoryError exception.

  • Revisited: static synchronized vs garbage collected

    A forum thread (http://forum.java.sun.com/thread.jsp?forum=4&thread=466049&start=0&range=15&hilite=false&q=) from last November addressed issues involving the relative merits of using static methods vs. the garbage collection issues that might attend conventional object instantiation. The discussion extended into use of synchronized code and threading, but from it, I've failed to gather an understanding of a few subtleties.
    I understand the dangers of using class-level variables within servlets, however, I'm still puzzled as to the thread-safety of 1) static class-level variables in servlets, and 2) using static methods residing in "utility" type classes from within servlets. I also realize these matters are not confined to servlets, but extend to any multi-threaded environment. I'm particularly unclear as to when, or if, the methods of the static class-level variable/objects need to be synchronized; with the same question applied to the static methods of the "utility" classes.
    From the forum thread mentioned above, it would seem that synchronization is NOT needed since parameters and method-level variables are specific to the executing threads. I believe this essentially means that static methods should not rely on the state of their containing class (under most applications). In a situation where the method's code is not trivial or "lightweight" (e.g. database access), would not the overhead associated with the swapping in and out of thread-specific variables lead to performance issues?
    My particular situation involves an ecommerce site running websphere. We are experiencing sporadic episodes where the VM starts running low on memory, will occasionally recover but will also occasionally crash. In pursuing this wild goose, my first suspicion was a thread deadlocking problem since it's not reliably reproducible. Most of the log entries point to a static method in one of these "utility" classes, yet I can find no non-static class level variables either in the utility or the servlet. However, none of these static methods are synchronized.
    Sorry for the ramble, and thanks for any help.
    Regards,
    Joe

    Because static variables, by their very nature, are only instantiated once, you MUST syncronise them to be safe in a multi threaded environment, otherwise you will get unexpected results.
    As you rightly mention, servlets also optimise the instantiation of class level variables and effectively make them static as well, so they are shared amongst all instaniations of a servlet.

  • Do you think JOptionPane dialogs force garbage collection afterwards?

    I ask because I've made a nested static class to implement my own file selection tool; the problem is that each time I call it the old JPanel is being recalled and so the components get re-added to it each time it's called, resulting in n versions of each file for every n times you open it.
    I'm running myDialog.dispose() upon exiting, so is my only option now manual garbage collection? How could I force it to be garbage collected? Because System.gc() seems to have no effect.

    Strictly speaking there is no way to force garbage collection, so, no, JOptionPane will not be doing it.
    You almost certainly have a leak in your code. Post it and we may be able to help.

  • Preventing garbage-collection of a RMIRegistered server object

    I am developping a client/server RMI application, and keep facing occasional ObjectNotFioundException: no such object in table, when the client tries to invoke method on the server stub retrived from the RMIRegistry.
    The Javadoc and online documentation say this means the server object has been GC'ed since it has been registered in the RMIRegistry.
    Following the advice found at: http://www.nabble.com/java.rmi.NoSuchObjectException:-no-such-object-in-table-t260095.html,
    I register the server in a RMIRegistry I obtain through LocateRegistry.getRegistry(), and not createRegistry().
    But I still face these exceptions.
    Assuming the issue is really due to the server object being garbage-collected, I tried to keep a static reference to the server but it didn't help (the Main class was probably garbage-collected itself).
    As a last hope, I've set up a "keep-alive" thread in the server VM, that keeps a direct reference to the server object (not the stub), and regularly invokes something on it. With this mechanism I never face the exception.
    This solution looks obviously clumsy.
    Is there a neater way to prevent garbage collection of the server object?
    Note that I use dynamic stubs (Java5-style).

    Without seeing some code, I'm not sure what you are doing. Also the link you supplied is broken.
    You always need to keep a live reference to your implementation class. How you do this is your business. Using a separate thread is over-kill.
    I set a reference to the implementation class in the start up class and use a never ending wait() to make sure the start up class thread (with the main()) lives forever.

  • NullPointer Exception ,web start Static class loading in sun JRE with JNLP

    I have a netbenas based application and using with jre 1.6.0_22.
    i am getting NPE as
    java.lang.NullPointerException
    at com.sun.deploy.security.CPCallbackHandler.isAuthenticated(Unknown Source)
    at com.sun.deploy.security.CPCallbackHandler.access$1300(Unknown Source)
    at com.sun.deploy.security.CPCallbackHandler$ChildElement.checkResource(Unknown Source)
    at com.sun.deploy.security.DeployURLClassPath$JarLoader.checkResource(Unknown Source)
    at com.sun.deploy.security.DeployURLClassPath$JarLoader.getResource(Unknown Source)
    at com.sun.deploy.security.DeployURLClassPath.getResource(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at com.sun.jnlp.JNLPClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at com.osi.solutions.platform.classbuilder.view.ClassExplorerTopComponent.<init>(ClassExplorerTopComponent.java:89)
    at com.osi.solutions.platform.classbuilder.view.ClassExplorerTopComponent.getDefault(ClassExplorerTopComponent.java:143)
    at com.osi.solutions.platform.classbuilder.view.ClassExplorerTopComponent$ResolvableHelper.readResolve(ClassExplorerTopComponent.java:198)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at java.io.ObjectStreamClass.invokeReadResolve(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at org.netbeans.modules.settings.convertors.XMLSettingsSupport$SettingsRecognizer.readSerial(XMLSettingsSupport.java:544)
    at org.netbeans.modules.settings.convertors.XMLSettingsSupport$SettingsRecognizer.instanceCreate(XMLSettingsSupport.java:576)
    at org.netbeans.modules.settings.convertors.SerialDataConvertor$SettingsInstance.instanceCreate(SerialDataConvertor.java:420)
    at org.netbeans.core.windows.persistence.PersistenceManager.getTopComponentPersistentForID(PersistenceManager.java:531)
    at org.netbeans.core.windows.persistence.PersistenceManager.getTopComponentForID(PersistenceManager.java:641)
    at org.netbeans.core.windows.PersistenceHandler.getTopComponentForID(PersistenceHandler.java:422)
    at org.netbeans.core.windows.PersistenceHandler.load(PersistenceHandler.java:147)
    at org.netbeans.core.windows.WindowSystemImpl.load(WindowSystemImpl.java:69)
    [catch] at org.netbeans.core.NonGui$2.run(NonGui.java:178)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:104)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
    This issue comes very occassionaly .
    Does someone have any idea what is wrong. Is this related to any jre bug.
    Thanks,
    totaram

    Hi I'm the one who posted those findings... though further investigation found that increasing your heap size can help, but at best it only reduces the occurances of the problem.
    The real cause of the issue is that the Signer's info for a CachedJarFile is held onto by softreferences and is not "rebuilt" if it has been garbage collected. the Reason that increasing your initial heap size works, is that it helps to delay the conditions on which these softreferences are garbage collected. (SoftReferences become eligible for garbage collection when the heap needs to be expanded)
    I've put together a hack that traverses all of the jars in a webstart application, finds their corresponding CachedJarFile instance and sticks all of the relevant SoftReferences into a static list, so that they become "hard references" and are never garbage collected.
    Below is my JarSignersHardLinker.java hack To use it, just call JarSignersHardLinker.go() it will then
    * Check that you are running on webstart and you are on java 1.6 update 19 or higher.
    * If the above is true then it will spawn a new thread and create hard links to all the jarsigners for each jar on the classpath.
    If you need more info email me on my gmail account. My user name is squaat. I've also posted this code at Re: Error with Java WebStart Signed Jars on 1.6.0_19's new Mixed  Code
    If you find this helpful and it solves your problems, please leave a positive comment and/or vote for the bug at:
    http://bugs.sun.com/view_bug.do?bug_id=6967414
    If any oracle/sun webstart engineers are reading this, please contact me... we'd really like this bug fixed.
    import java.io.IOException;
    import java.lang.ref.SoftReference;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.net.JarURLConnection;
    import java.net.URL;
    import java.net.URLConnection;
    import java.util.ArrayList;
    import java.util.Enumeration;
    import java.util.LinkedHashSet;
    import java.util.List;
    import java.util.Set;
    import java.util.jar.JarFile;
    * A utility class for working around the java webstart jar signing/security bug
    * see http://bugs.sun.com/view_bug.do?bug_id=6967414 and http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6805618
    * @author Scott Chan
    public class JarSignersHardLinker {
        private static final String JRE_1_6_0 = "1.6.0_";
         * the 1.6.0 update where this problem first occurred
        private static final int PROBLEM_JRE_UPDATE = 19;
        public static final List sm_hardRefs = new ArrayList();
        protected static void makeHardSignersRef(JarFile jar) throws java.io.IOException {
            System.out.println("Making hard refs for: " + jar );
            if(jar != null && jar.getClass().getName().equals("com.sun.deploy.cache.CachedJarFile")) {
                 //lets attempt to get at the each of the soft links.
                 //first neet to call the relevant no-arg method to ensure that the soft ref is populated
                 //then we access the private member, resolve the softlink and throw it in a static list.
                callNoArgMethod("getSigners", jar);
                makeHardLink("signersRef", jar);
                callNoArgMethod("getSignerMap", jar);
                makeHardLink("signerMapRef", jar);
    //            callNoArgMethod("getCodeSources", jar);
    //            makeHardLink("codeSourcesRef", jar);
                callNoArgMethod("getCodeSourceCache", jar);
                makeHardLink("codeSourceCacheRef", jar);
         * if the specified field for the given instance is a Softreference
         * That soft reference is resolved and the returned ref is stored in a static list,
         * making it a hard link that should never be garbage collected
         * @param fieldName
         * @param instance
        private static void makeHardLink(String fieldName, Object instance) {
            System.out.println("attempting hard ref to " + instance.getClass().getName() + "." + fieldName);
            try {
                Field signersRef = instance.getClass().getDeclaredField(fieldName);
                signersRef.setAccessible(true);
                Object o = signersRef.get(instance);
                if(o instanceof SoftReference) {
                    SoftReference r = (SoftReference) o;
                    Object o2 = r.get();
                    sm_hardRefs.add(o2);
                } else {
                    System.out.println("noooo!");
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
                return;
            } catch (IllegalAccessException e) {
                e.printStackTrace();
         * Call the given no-arg method on the given instance
         * @param methodName
         * @param instance
        private static void callNoArgMethod(String methodName, Object instance) {
            System.out.println("calling noarg method hard ref to " + instance.getClass().getName() + "." + methodName + "()");
            try {
                Method m = instance.getClass().getDeclaredMethod(methodName);
                m.setAccessible(true);
                m.invoke(instance);
            } catch (SecurityException e1) {
                e1.printStackTrace();
            } catch (NoSuchMethodException e1) {
                e1.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
         * is the preloader enabled. ie: will the preloader run in the current environment
         * @return
        public static boolean isHardLinkerEnabled() {
             boolean isHardLinkerDisabled = false;  //change this to use whatever mechanism you use to enable or disable the preloader
            return !isHardLinkerDisabled && isRunningOnJre1_6_0_19OrHigher() && isRunningOnWebstart();
         * is the application currently running on webstart
         * detect the presence of a JNLPclassloader
         * @return
        public static boolean isRunningOnWebstart() {
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            while(cl != null) {
                if(cl.getClass().getName().equals("com.sun.jnlp.JNLPClassLoader")) {
                    return true;
                cl = cl.getParent();
            return false;
         * Is the JRE 1.6.0_19 or higher?
         * @return
        public static boolean isRunningOnJre1_6_0_19OrHigher() {
            String javaVersion = System.getProperty("java.version");
            if(javaVersion.startsWith(JRE_1_6_0)) {
                //then lets figure out what update we are on
                String updateStr = javaVersion.substring(JRE_1_6_0.length());
                try {
                    return Integer.parseInt(updateStr) >= PROBLEM_JRE_UPDATE;
                } catch (NumberFormatException e) {
                    //then unable to determine updatedate level
                    return false;
            //all other cases
            return false;
          * get all the JarFile objects for all of the jars in the classpath
          * @return
         public static Set<JarFile> getAllJarsFilesInClassPath() {
              Set<JarFile> jars = new LinkedHashSet<JarFile> ();
             for (URL url : getAllJarUrls()) {
                 try {
                     jars.add(getJarFile(url));
                 } catch(IOException e) {
                      System.out.println("unable to retrieve jar at URL: " + url);
             return jars;
         * Returns set of URLS for the jars in the classpath.
         * URLS will have the protocol of jar eg: jar:http://HOST/PATH/JARNAME.jar!/META-INF/MANIFEST.MF
        static Set<URL> getAllJarUrls() {
            try {
                Set<URL> urls = new LinkedHashSet<URL>();
                Enumeration<URL> mfUrls = Thread.currentThread().getContextClassLoader().getResources("META-INF/MANIFEST.MF");
                while(mfUrls.hasMoreElements()) {
                    URL jarUrl = mfUrls.nextElement();
    //                System.out.println(jarUrl);
                    if(!jarUrl.getProtocol().equals("jar")) continue;
                    urls.add(jarUrl);
                return urls;
            } catch(IOException e) {
                throw new RuntimeException(e);
         * get the jarFile object for the given url
         * @param jarUrl
         * @return
         * @throws IOException
        public static JarFile getJarFile(URL jarUrl) throws IOException {
            URLConnection urlConnnection = jarUrl.openConnection();
            if(urlConnnection instanceof JarURLConnection) {
                // Using a JarURLConnection will load the JAR from the cache when using Webstart 1.6
                // In Webstart 1.5, the URL will point to the cached JAR on the local filesystem
                JarURLConnection jcon = (JarURLConnection) urlConnnection;
                return jcon.getJarFile();
            } else {
                throw new AssertionError("Expected JarURLConnection");
         * Spawn a new thread to run through each jar in the classpath and create a hardlink
         * to the jars softly referenced signers infomation.
        public static void go() {
            if(!isHardLinkerEnabled()) {
                return;
            System.out.println("Starting Resource Preloader Hardlinker");
            Thread t = new Thread(new Runnable() {
                public void run() {
                    try {
                        Set<JarFile> jars = getAllJarsFilesInClassPath();
                        for (JarFile jar : jars) {
                            makeHardSignersRef(jar);
                    } catch (Exception e) {
                        System.out.println("Problem preloading resources");
                        e.printStackTrace();
                    } catch (Error e) {
                         System.out.println("Error preloading resources");
                         e.printStackTrace();
            t.start();
    }Edited by: 855200 on 04-Jul-2011 17:31

  • Static class reference

    Below we have a class containing a static class variable and a static accessor method.
    The method is responsible for assigning the variable, which it does on demand.
    public class MyClass
        private static int INFO = -1;
        public static int getInfo()
            if(INFO < 0)
                try
                    INFO = ...;
                catch(Exception e)
            return INFO;
        }When using this class is it not safe to assume that the assignment of the variable will ever only occur once for the life of the system that uses this class? (afterall is it static within the class)
    I am experiencing the situation whereby EVERY time the method is called, the assignment of the variable is necessary. I can only assume that the static instance of this class in memory has been lost between each call and therefore the state/value of the variable has also been lost.
    It is worth noting that no object instances of this class are ever created. The class is accessed only through its static interface. It seems that since no local reference to objects of this class are held in memory then the entire class, along with its internal static state, is cleared from memory (garbage collected?).
    How is it possible to ensure that the state of static fields within such a class is preserved over time, without create instances of the class.
    John

    When using this class is it not safe to assume that
    the assignment of the variable will ever only occur
    once for the life of the system that uses this class?First of all, you haven't said what you assign it to, so we can't say. If you assign a value less than zero then it will be reassigned next time the method is called.
    Secondly, it depends on whether or not you're expecting it to be thread-safe? It isn't.
    If your code is not multi-threaded, then the section of code in your getInfo method that assigns the field should only execute once during a single run of an application.
    Thirdly, you explicitly assign it (to minus one) at class initialisation time, so stricty speaking, the variale will always be assigned at least once, and will be assigned at least once more if the getInfo method is ever called.
    I am experiencing the situation whereby EVERY time the
    method is called, the assignment of the variable is
    necessary. Can you offer any evidence to this? A small, complete, compilable and executable example that demonstrates the problem will help, and will probably get you an answer pretty quickly around here.
    I can only assume that the static instance
    of this class in memory has been lost between each
    call and therefore the state/value of the variable has
    also been lost.Then either there is a bug in your JVM, or at least two versions of the class have been loaded, and at least one of those was not loaded by the system classloader. Without further info, we aren't going to be able to help much more here.
    The class is accessed only
    through its static interface. It seems that since no
    local reference to objects of this class are held in
    memory then the entire class, along with its internal
    static state, is cleared from memory (garbage
    collected?).This is not allowed under the JLS if the class was loaded by the system classloader. If it was loaded by another classloader, then it is only allowed if it can be determined that the class will never again be used throughout the entire run of the application. Since you are referencing the class again, this should not be happening.
    How is it possible to ensure that the state of static
    fields within such a class is preserved over time,
    without create instances of the class.From what you have told us so far, it should be. You will probably have to provide some code for us to help you further.

  • This byte array is not garbage collected?

    imageBytes[] does not seem to ever be garbage collected. I've pinpointed a SINGLE LINE that, when commented out, will prevent the memory leak. What could possibly be wrong with this line?
    Running this code results in a "OutOfMemoryError: Java heap space" after roughly a minute on my machine. I'm using JRE version 1.5.0_08.
    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.*;
    import java.io.*;
    // creates images to send to ImageConsumer
    public class ImageProducer {
         static BufferedImage bufferedImage;
         static Robot robo;
         static byte[] imageBytes;
         public static void main(String args[]) {
              try {
                   robo = new Robot();
              } catch(Exception e) {
                   e.printStackTrace();
              PipedOutputStream pos = new PipedOutputStream();
              new ImageConsumer(pos).start();
              bufferedImage = robo.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
              try {
                   ObjectOutputStream oostream = new ObjectOutputStream(pos);
                   ByteArrayOutputStream baos = new ByteArrayOutputStream();
                   ImageIO.write(bufferedImage, "JPG", baos);
                   baos.flush();
                   imageBytes = baos.toByteArray();
                   while (true) {
                        ImageIO.write(bufferedImage, "JPG", baos);
                        baos.flush();
                        // THIS SEEMS TO BE WHERE THE MEMORY LEAK OCCURS: imageBytes
                        // If you comment the following line out, there will be no
                        // memory leak. Why?  I ask that you help me solve this.
                        imageBytes = baos.toByteArray();
                        baos.reset();
                        oostream.writeObject(imageBytes);
                        pos.flush();
              } catch (Exception e) {
                   e.printStackTrace();
    // This thread reads the image data into bImg
    class ImageConsumer extends Thread {
         BufferedImage bImg;
         PipedInputStream pis;
         ImageConsumer(PipedOutputStream pos) {
              try {
                   pis = new PipedInputStream(pos);
              } catch (IOException e) { e.printStackTrace();}
         public void run() {
              try {
                   ObjectInputStream oinstream = new ObjectInputStream(pis);
                   while (true) {
                        byte[] imageBytes = (byte[])oinstream.readObject();
                        ByteArrayInputStream bais = new ByteArrayInputStream(imageBytes);
                        bImg = ImageIO.read(bais);
              } catch (Exception e) {e.printStackTrace();}
    }

    while (true) {
         ImageIO.write(bufferedImage, "JPG", baos);
         baos.flush();
         // THIS SEEMS TO BE WHERE THE MEMORY LEAK OCCURS: imageBytes
         // If you comment the following line out, there will be no
         // memory leak. Why? I ask that you help me solve this.
         imageBytes = baos.toByteArray();
         baos.reset();
         oostream.writeObject(imageBytes);
         pos.flush();
    }I have only briefly gone through the code, but why are you flushing it right before calling that line. Won't the byte array returned always be empty right after flushing the stream?

  • Garbage-collecting the cloned objects

    public class Clone implements Cloneable {
    public static void main(String[] arg) {
    Clone i0, i1;
    i0 = new Clone();
    System.out.println("Created: " + i0);
    try{
    i1 = (Clone)i0.clone();
    System.out.println("Cloned: " + i1);
    } catch(CloneNotSupportedException e){
    e.printStackTrace();
    i0 = null;
    i1 = null;
    System.gc();
    public Object clone() throws CloneNotSupportedException {
    return super.clone();
    public void finalize() {
    System.out.println("Finalizing " + this);
    With the example above you can notify that with Hotspot VM of JDK1.3 the
    finalize() method will not be called for the cloned object; though,
    running the sample with the classic VM, the finalize() will be
    called for both objects.
    Bypassing the finalize() can be made intended, in order to avoid
    multiple "release" or "close" calls on the same object, eg. if the
    finalize() has to close a file or a JDBC-connnection. But then why
    is it called in the classic VM? Is it sure that the cloned object
    too will be garbage-collected?

    Here's the proper way to write a clone() method:
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
    }There's no reason for a clone() method to declare that it throws CloneNotSupportedException. Doing so just makes code that uses the clone() method more complicated unnecessarily.
    Here's the proper way to write a finalizer:
    protected void finalize() {
        try {
            // perform subclass cleanup
        } finally {
            super.finalize();
    You should always make finalize() protected to help ensure that only the garbage collector calls it, and it should always call super.finalize() to ensure that the superclass finalization can happen.
    Now, to your question. There's no way to guarantee that an object will be garbage collected or finalized. In fact, finalizers are so notoriously hard to write correctly that Java 2 added PhantomReferences to allow a simpler way to clean up objects.
    If you want an object to release resources, such as closing a file or releasing a database connection, provide a close() or dispose() or release() method in the class and close the resources there. Even if you could guarantee that your finalizer is called or if you used PhantomReference queues to perform cleanup, this cleanup would probably not happen in a timely manner. Finalizers are not C++ destructors -- if you need to release resources, add a method to do that.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

  • GUI Garbage Collection

    Hi Everyone.
    This is very urgent. I need to perform a possible garbage collection of a heavy GUI stuff when it is not in use. Each of the GUI stuff is created from an action listener for the various menu items. I did try using WeakReference but its very hard to know that when the collection will take place.
    Here is the code snippet for the situation...
    //this is application's main frame class...
    public class MyApplication extends JFrame
    JMenuItem menu1, menu2;
    WeakReference ref_MyPanel;
    //earlier it was a strong reference of MyPanel over here
    public static void main(String [] args)
    //instantiating this class and showing that here ...
    //This is called from menu1's action listener..
    void showGUI()
    JFrame f = new JFrame();
    if(ref_MyPanel.get()!=null)
    f.getContentPane().add((MyPanel)ref_MyPanel.get());
    else
    MyPanel mp = new MyPanel();
    ref_MyPanel=new WeakReference(mp);
    f.getContentPane().add(mp);
    mp=null;//clearing the strong refernce
    f.show();
    //A GUI class which needs to be reclaimed when done
    class MyPanel extends JPanel
    double [] a;
    MyPanel1()
    a = new double [1000000]; //making the panel instance heavy
    What i want is to reclaim the memory occupied by MyPanel instance after its Frame being closed. I even tried calling the System.gc() from the MyPanel instance's parent frame's WindowListener -> windowClosed() but it didn't help. Actually this is suffering me a lot as there are several menu items and several GUIs are being instantiated similar to those of MyPanel as shown above. Do i need to change this design to achieve the objective?
    Can anyone help?

    We saw a significant memory improvement in our system when we used this
    utility. Try using this handy class to recursively remove each component
    For JFrames & JApplets I think it was
    ComponentCleaner.cleanComponent ( myFrame.getContentPane() );
    For Frames & Applets
    ComponentCleaner.cleanComponent ( myFrame );
    Also, for every addActionListener(), addComponentListener() etc call,
    you want a removeActionListener(), removeComponentListener() call.
    The listeners store references to the visual components if I remember rightly. So avoid anonymous listener classes, and have proper cleanup methods to remove the listeners.
    (code below)
    regards,
    Owen
    import java.awt.Container;
    import java.awt.Component;
    import javax.swing.RootPaneContainer;
    public class ComponentCleaner
        public static void cleanComponent(Component baseComponent)
            if (baseComponent == null) // recursion terminating clause
                return ;
            Container cont;
            Component[] childComponents;
            int numChildren;
            // clean up component containers
            if(baseComponent instanceof Container)
                // now clean up container instance variables
                if (baseComponent instanceof RootPaneContainer)
                   // Swing specialised container
                    cont = (Container)baseComponent;
                    numChildren = cont.getComponentCount();
                    childComponents = cont.getComponents();
                    for(int i = 0;i < numChildren;i++)
                        // remove each component from the current container
                        // each child component may be a container itself
                        cleanComponent(childComponents);
    ((RootPaneContainer)cont).getContentPane().remove(childComponents[i]);
    ((RootPaneContainer)cont).getContentPane().setLayout(null);
    else
    { // General Swing, and AWT, Containers
    cont = (Container)baseComponent;
    numChildren = cont.getComponentCount();
    childComponents = cont.getComponents();
    for(int i = 0;i < numChildren;i++)
    // remove each component from the current container
    // each child component may be a container itself
    cleanComponent(childComponents[i]);
    cont.remove(childComponents[i]);
    cont.setLayout(null);
    } // if component is also a container

  • A question about JNI references, persistence, and garbage collection

    I am writing a library to allow our Java developers to access C functions in our product. I want people on the Java side to be able to instantiate instances of a new object (on the C side), say "Map", and I want those objects to persist until they are destroyed on the Java side. I am thinking of creating a wrapper for the native methods, which stores an identifier for the instance of an object. When the C object is accessed, the identifier is passed to the C code which looks up the correct object in a table. I understand that if I use the NewGlobalReference call in JNI I can get objects to persist.
    When it is time for garbage collection I plan to override finalize() to call the C code and tell it to remove the Global Reference.
    Here's what I have in mind
    public class JMap() {
         private static int id;
         static {
              System.loadLibrary("libMap");
              /*Call C method which instantiates object and creates a GlobalReference
              which is stored in table. Returns ID for reference*/
              id = _init();
         public void setSize(int x, int y) {
              _setSize(id, x, y);
         public void finalize() {
              _finalize(id);
              super.finalize();
         private native int _init();
         /*calls DeleteGlobalReference for the reference matching this id*/
         private native void _finalize(int id);
         private native void _setSize(int id, int x, int y);
    }Is this the right thing to do? Have I understood the way JNI works with regard to GlobalReferences?
    Any comments, tips or pointers would be appreciated :)

    This probably should have been posted in the Native Methods sub-forum, I have reposted there:
    http://forum.java.sun.com/thread.jspa?threadID=657667
    Mods please delete this post :)

  • Nested object reference after garbage collection

    I have a question about how GC works.
    Assume I have a Class A which has a reference to class B inside it. I create a object of class B and assign to member variable of class A.
    Now when obja is no longer needed, I set it null. And when GC runs, the object will be removed from memory. But should I also need to explicitly set objb to null. If i don't set it, will it also get garbage collected when obja is being removed from memory?
    public class ClassA {
    private ClassB objB = new ClassB();
    private static void main(String args[]) {
    ClassA obja = new ClassA();
    obja = null;
    }

    801625 wrote:
    But should I also need to explicitly set objb to null.No.
    If i don't set it, will it also get garbage collected when obja is being removed from memory?If there are no other references outside of classA to the object referenced by objB (in your case an instance of ClassB) then it will be garbage collected.
    Note - the only time one needs to set a reference to null is if one wants the object it references to be eligible for GC before the reference goes out of scope. There is a slight complication to this - depending on the JVM implementation, if a reference is defined in a block internal to a method then even though it goes out of scope when execution goes out of the block anything it references may not be eligible for GC until the method exits.

  • All Tweens randomly halting (Not Garbage Collection)

    I am developing a game with some AS3 tweens. I have encountered the problem of garbage collection affecting tweens before so I have all my tweens referenced at the class level now to ensure that isn't a problem. However, randomly all the current tweens in my game will stop. Other, non-tweened, frame by frame animations continue. It's just like the garbage collection problem but the tweens shouldn't be being collected...
    The code I am using for tweens:
    Var declaration at the top of the class:
    private var gateTween:Tween;
    This code in a function:
    gateTween = new Tween(currentGate, "x", None.easeOut, 800, 380, 1.5, true);
    gateTween.addEventListener(TweenEvent.MOTION_FINISH, horseJump);
    Any ideas would be appriciated.

    I have Swing based java project. Im setting all the
    references to null as and when i dont need them, and
    then im calling System.gc() also.
    However it seems the memory is not being released,
    when i check in the task manager, memory usage does
    not reduce. It seems garbage collection is not
    happening.Actually I have a small class - where in I try to do this:-
    public class TestDebug extends Object{
    /** Creates a new instance of TestDebug */
    public TestDebug() {
    * @param args the command line arguments
    public static void main(String[] args) {
    System.out.println("Trying to debug this");
    TestDebug testDebug = new TestDebug();
    testDebug.finalize();
    System.out.println("Lasting print");
    public void finalize(){
    System.out.println("Finalize called");
    System.gc();
    System.out.println("Finalize finished");
    But it is also true that you should never try to force it - It has its own way to do it.
    For Example try to execute a big code(so that you can find JVM doing the GC) as "java -verbose:gc class-name"
    You will find at some points during the execution process - that the JVM actually runs the GC on its own- but when not that is not defined.It is a low priority thread running under JVM.

  • Garbage Collection facilitation by assigning variables to null

    Hello,
    I understand Garbage Collection (GC) can be facilitated by assigning variables to null. Is this true for all variables?
    I have a class and there are some member variables which are strings. Also i have some methods with some string variables declared and defined inside the method. I am assigning null to class member variables and also the string variables of the method.
    is it correct to assign null and faciliate GC for the string variables declared and defined inside the method?
    Class A {
    String t1;
    public void test() {
    String t2 = "test";
    // processing
    t2 = null; // Will this facilitate GC?
    public static void main (String[] args) {
    test();
    A obj = new A();
    A.t1 = "testclass";
    A.t1 = null; // Will this faciliate GC?
    Thanks, Aravinth

    In fact, the java heap is divided into a space for new allocations, and two survivor spaces. The algorithm for when collection occurs in each space is complex, and tuning GC is an interesting topic all its own. Follow the best advice you have been given ... chillax. The JVM has GC under control.
    <think/> Of course, having said this, you can have memory leaks if you create references that never go out of scope, even if they are no longer used. Avoid this.
    � {�                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

Maybe you are looking for