tags:

views:

692

answers:

6

I have 2 classes, let's call the class A and class B.

public class A{
private static HashMap<String,B> isc= new HashMap<String,B>();

public static void UserDisconnected(String key){
    if(isc.containsKey(key)){
     if(isc.get(publicSID).timer != null){
      isc.get(key).timer.cancel();
      isc.get(key).timer=null;
     }
     isc.remove(key);
    }
    log.debug("isc size:" + isc.size());
}

//and other non-static variables and methods

}

public class B{
//contain no static variables and methods
public void startStream(){
    timer = new Timer();
    timer.schedule(new timedTask(), 0, interval);
}

public class timedTask extends TimerTask{
    public void run(){
        //do something
    }
}

Class A will live through the entire lifetime of the application while the instances of class B that is referenced in the hashmap(isc) that is in Class A. The problem is, after i run UserDisconnected() method in class A, i see that the size of isc is 0, but the memory usage as shown in the task manager of windows server 2008 down go back down, don't see any memory being freed. So, i wonder, were the instances of class B in the hashmap garbage collected? or are they lost somewhere where the garbage collector couldn't even collect it.

Thanks.

+2  A: 

I don't think you'd expect to see the memory usage in Task Manager go down. The memory which was used is returned to Java for future use, not returned to the OS for other apps.

Matthew Wilson
That would depend to some degree on the VM, I think. A small voice in head is telling me that the Hotspot Client VM is more likely to release memory back to the OS, but the Server VM will just keep it.
skaffman
So, there's nothing wrong in the codes that might cause memory leak, right?Is there a way to return the memory to OS?
If you're freeing all references to the objects, they will be garbage collected in due course (it won't necessarily happen immediately). I don't think you are able to return memory to the OS programatically.
Matthew Wilson
+2  A: 

One thing you should know is that the Windows task manager is displaying the memory your Java JVM heap is allocated by the operating system. The number doesn't go up or down as the GC runs.

Maybe you should try WeakHashMap if you're worried about memory and hanging onto references too long.

I'd also recommend using the interface Map as the type for isc.

duffymo
A: 

You can't use Windows Task Manager to know exactly how much memory your program uses, because the JVM will still have a hold of the memory, even though no objects are using it. It is more effective for the JVM and its GC algorithms to reserve more memory than the program actually uses. To find out the actual memory usage, you need a tool such as VisualVM (it comes also with the latest JDKs).

Esko Luontola
A: 

As others have noted, the JVM does not generally return memory freed by GC to the OS.

To see the ratio between used and free memory within the JVM, use VisualVM, and you can also use its memory profiling (via heap snapshot functionality) to track down the causes of memory leak.

The JVM does return memory to the OS, but its default settings are to do this very reluctantly, only when it has much more free than used memory. You can tune this behaviour via the -XX:MinHeapFreeRatio and -XX:MaxHeapFreeRatio options.

Michael Borgwardt
+1  A: 

There is only one answer:

profile your application.

with one of http://www.google.com/search?q=java+profile these prfoilers you know exactly when and if any classes are not clean up after using.

Peter
A: 

Downloaded and using VisualVM now, the graphs and charts are so pretty... Anyway, i'll profile the application using it. Thanks a lot guys.