This question already has answers here:
Deleting an object in java?
(7 answers)
Closed 9 years ago.
I have an object called CounterGUI. It creates a GUI. I create it in another class, say MyProgram.
Once MyProgram creates a CounterGUI object, how do I delete the object? Say if I do this:
CounterGUI first = new CounterGUI(); //displays the GUI
first = null;
I thought setting the object to null would delete everything (including the GUI), but it doesn't. How do I completely delete it?
I don't see how this is a duplicate question, the previous answers were to set it to null or a new object, but that doesn't work here.
Assuming that CounterGUI is a java.awt.Window, then:
The way to make the window disappear is to call setVisible(false).
The way to disconnect it entirely from the native windowing is to call dispose().
Once the Window has been disposed, making it unreachable (e.g. by assigning null to all of your variables that reference it) will make it eligible for garbage collection.
Simply assigning null while the Window is visible will have no effect. The a visible Window object is connected to various things that prevent it from being garbage collected.
Java uses automatic garbage collection. When you set an object to null and it is the last reference remaining, the JVM will reclaim the memory used.
In your case, however, it may be that a thread is created (with GUIs this is often the case) and a reference to the current object is given to it. In this case, setting the reference to null has no effect as something else still has access to the object.
In order to properly close your GUI, you have to invoke a close method. For a JFrame, you can try this:
myGui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
which will close the application when the user clicks the close button. If you want to control closing by the program, then you can try:
private void closeItDown() {
WindowEvent event = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(event);
}
...and calling this method. You don't have to set anything to null, the JVM will garbage collect for you at this point, maybe. Not guaranteed, but possibly at this point, perhaps later, or now... or whenever :)
Deleting an object by setting its reference to null make it eligible for garbage collection and JVM will take care of removal of all those object. If you wants to force the garbage collector to run you can issue System.gc() or Runtime.gc () but it is still not a guarantee that it will be collected back to JVM. You can find further information on how garbage collector works here
If you wants to remove your GUI window you can use dispose() method.
you want to make disappear GUI then dispose()
you dont have to worry about this , Garbage collector will automatically take it out of memory or
you can invoke it yourself
System.gc()
but it is bad practice as well as not guaranteed that it will surely being collected.
Related
I have developed simulation software for a robotics competition coming up. This software's purpose is to learn how to play a game using NEAT.
To do this the simulation must be run many many many times. However, I've just recently noticed a bad memory leak in the program. It appears that every 10 seconds 1 more mb of memory is allocated.
I believe that the memory leak lies within my Game class because this class is actually responsible for running through the simulation.
My question is:
If I were to set game to null before starting another game would that allow the garbage collector to deallocate every child object within game or do I also have to set those to null.
Would this do the trick?
{
//=-=-=-=-=-=-=-=-=--=-=-=-=-=-=
Game game = new Game(someParams);
while(!(game.isFinished()))
{
game.run();
game.draw();
}
//do some stuff for NEAT
//remove the memory
game = null;
System.gc();
//=-=-=-=-=-=-=-=-=-=-=-=-=-
}
At the beginning of this method you assign a brand new instance to game. Setting it to null at the end might help depending on what you do after. If this is the end of the method, the setting it to null will change nothing, because the game reference is destroyed immediately after (as if you had assigned null). If you continue doing things in the same method after setting it to null, it might help, but it won't be the final solution.
Memory leaks in Java usually happen because you forget to release a reference to an object. For instance adding it to a list, and forgetting to remove it when you are over with it.
JDK provides some tools for that:
$ jmap -dump:format=b,live,file=/tmp/dump <pid>
$ jhat /tmp/dump
jhat creates a HTTP server listening on port 7000. Open http://localhost:7000 with your browser and at the end of the first page you'll find the option "Show instance counts for all classes (excluding platform)."
Click on it and you will see a list of all the loaded classes, ordered by the number of instances. One or two of the classes will have an abnormally-high number of instances. Click on "instances" and you will have the list of all the instances for that class.
Clicking on one of the instances you'll see the actual object, and under "References to this object" a list of objects keeping a reference to it.
Some referencing objects will have valid references to it. Others might have a forgotten reference. Try to identify which object (a List, a Map, a Set, etc), keeps a forgotten reference by checking several instances of the objects which is not being released.
I have created an object whose finalize method has been overridden to save and close the file with some information. That object is weak referenced from another object. I want to save some changes to the object when GC happens. That's why I have overridden the code for finalize.
But, the finalize method is called when an object is about to get garbage collected. That can be at any time after it has become eligible for garbage collection.
I dont want this, I want to call the finalize method as soon as GC happens, and there should not be any lag. Is there any jvm option which I can set to achieve this ??
There is only one other way which I can see is "System.runFinalization()", but that seems tacky??
Is there a more elegant way?
Thanks
I want to call the finalize method as soon as GC happens,
You can't without using internal APIs I wouldn't recommend you use.
there should not be any lag.
There is always lag. Just closing the file will take many milli-seconds. Are you okay with the application freezing while this happens (because the application can freeze while the GC is running)
Is there a more elegant way?
Close the resource when you finish with it if you want to to happen deterministically.
I have some objects that are created/destroyed very often and that can exist in many lists at the same time. To ensure I have no references left to them the objects have a flag isDestroyed, and if this is set, each list is responsible for removing the object from the list.
However this is ofcourse a growing ground for memory leaks. What if I forget to remove objects from one of the lists? To visually monitor that the program behaves correctly, I override finalize and increase a global variable to track destructions (not a formal test, only to get an idea). However as I have no control over the GC, I could in theory wait forever until something is destroyed.
So the question is two-fold: When having objects that are in multiple lists, is a "isDestroyed" considered a good way to control the object lifetime? It forces everyone who uses the object to take care to remove it from their lists, which seems bad.
And, is there any good way to see when the reference count reaches zero on an object, ie when its scheduled for destruction?
EDIT: To be more specific, in my case I my objects represent physical entities in a room. And I have one manager class that draws each object, therefore it is in one list. Another list contains all the objects that are clickable, so there I have another list. Having all objects in one list and using polymorphism or instance of is not an option in this case. When a object is "destroyed", it should neither be shown or clickable in any way, therefore I want to remove it from both lists.
You should have a look at the java.lang.ref Package.
And, is there any good way to see when the reference count reaches
zero on an object, ie when its scheduled for destruction?
You can use the ReferenceQueue Object
From JavaDoc of java.lang.ref.ReferenceQueue
Reference queues, to which registered reference objects are appended
by the garbage collector after the appropriate reachability changes
are detected.
I think this what WeakReference and ReferenceQueue is for - you create a WeakReference for the object you are tracking and associate it with a ReferenceQueue. Then you have another thread that processes WeakReference(s) as it is returned from ReferenceQueue.remove(). WeakReference's are added to ReferenceQueue when the referenced objects is GC'd. But can you give an example on what these lists you are trying to clean up when the referenced objects are dead?
The way this is usually handled is through the Observer pattern. Each list attaches a destroy-listener that gets notified upon destruction. How this meshes with you architecture, I have no details to judge from.
If you want to be notified I'm almost sure you need PhantomReference, read here:
http://weblogs.java.net/blog/2006/05/04/understanding-weak-references
Situation: a main form calls a modal jDialog with textboxes in which parameters are filled in by the user to create or modify an instance of a certain class, call it ClassA.
When the dialog needs to modify an existing instance, it is passed in the constructor as a parameter. Otherwise the jDialog will create a new instance of ClassA.
Problem: the mainform needs to access that new instance, and I think it is unclean code to pass the entire main form as a parameter, and let the dialog push the new instance into it by a method call, because that way a perfectly re-usable stand-alone dialog becomes only usable with one single main form that needs a certain classname and method to receive the new instance.
It is much more logical to make the main form get the new instance from the jdialog after the OK button is clicked, by calling a getClassAInstance() method (which could be called also when an existing instance was being modified). The method is called after the "setVisible(true)" method on a new instance of the jdialog in question. The dialog appears, the thread of the main form will sleep until the dialog is closed (because it is modal). The OK button calls the dispose() method of the jDialog, then the very next statement is the getClassAInstance() call on the jDialog by the mainform.
Here's the same thing in code..
ClassAInstanceMakerDialog imd = new ClassAInstanceMakerDialog(this, true);
imd.setVisible(true);
//imd.dispose(); after OK button click
System.out.println(imd.getClassAInstance()); //return a new ClassA instance
//output: whatever ClassA.toString() should return, works fine
Question: I've tried it and it seems to work perfectly fine. But, is it a good code? Is there any danger of the getClassAInstance() method returning "null", because the garbage collector collected the ClassA instance after the jDialog was disposed and before the main form could complete the call?
Please excuse me if I didn't make myself clear, I'm not a native English speaker. If you would rather see some code, let me know...
I think it's perfectly legal to access the member variable of your dialog instance that holds the ClassA instance, the dialog instance will not be garbage collected until it goes out of scope, not just because you called dispose on it.
I'd give slight preference to a solution where you define an event handler interface with a signature of
someThingHappened(ClassA toThisObject), make your mainform or anything that might be interested that ClassA thing implement that interface make it possible to add listeners to the dialog before making it visible.
That way, you would loosen the coupling between the dialog and the main form a little.
I don't think that dispose() sets the JDialog up for garbage collection, but instead just releases resources. The dialog is still re-usable as per the Window API (since JDialog inherits this method from Window):
Releases all of the native screen resources used by this Window, its subcomponents, and all of its owned children. That is, the resources for these Components will be destroyed, any memory they consume will be returned to the OS, and they will be marked as undisplayable.
The Window and its subcomponents can be made displayable again by rebuilding the native resources with a subsequent call to pack or show. The states of the recreated Window and its subcomponents will be identical to the states of these objects at the point where the Window was disposed (not accounting for additional modifications between those actions).
Note: When the last displayable window within the Java virtual machine (VM) is disposed of, the VM may terminate. See AWT Threading Issues for more information.
As long as there are valid reachable references to the JDialog object still present, it will not be garbage collected. I think that the cost of disposing the dialog is that your code will need to spend a (very) little bit of time to re-create the resources.
It is perfectly reasonable and appropriate to have an IDisposable include properties or methods which may be used after Dispose is called to return information about things which happened before Dispose was called. Rather than blindly enforcing a rule that any and all methods of a disposed object should throw an ObjectDisposedException, one should instead consider which methods and properties do or do not make sense on disposed objects. Attempting to access a disposed object should throw ObjectDisposedException in preference to re-acquiring released resources or letting escape some other exception which occurs as a consequence of the disposal. If the method or property access can succeed without any of the released resources, it should often be allowed to do so.
Is there a way to create register a handler that will be called exactly at the time when the last reference to a certain object is released?
An example would be an object that is backed by a physical data file and once the object become unreferenced, the file should be closed and than renamed. It would be nice if this was possible without having to explicitly call a "close" method on that object.
All the notification mechanisms I am aware of from the Weak/Phantom reference area only state that notification will occur at some point in time but there is no gurantee as to when this will happen...
In short, no.
The Java specification explicitly denies you the ability to know when the last reference is released. JVM implementations (and optimizations) depend on this. There is no hook.
From my understanding, and I've looked for some time to find a "destructor" for java objects, there is no way to know when you lose the last reference. Java tracks references to objects but for performance reasons, updates this information only during garbage collection.
The closest thing is the finalize method which should be called during garbage collection but there's no guarantee that it will be called even then.
I think WeakReference does what you want. A WeakReference gets put into the ReferenceQueue as soon as its weakly reachable (i.e. all strong references are gone).
See this article by Ethan Nicholas.
If you are worried about some references not reaching the ReferenceQueue at shutdown, then keep a list of all objects created (using WeakReferences or PhantomReferences). Add a shutdown hook that checks the list for any outstanding references and perform whatever action you need.
Problem is, "How do you implement this, without something holding a reference to the object?"
Even if you could get passed that problem, say with a service we'll call the HandleManager, the HandleManager would then have to create a new reference to the object, to pass to your handler. Then, your handler could either (a) store a reference to it, which would confuse the HandleManager which was expecting to destroy the unreferenced object; or (b) release the reference, which means that the final reference was once again released, which means the Handler has to be called again....
If you need to manage external resources like files, the best you can do in java is a close() function (whatever name you choose). You can use finalize() as a "belt and suspenders" insurance policy, but that has unpredictable timing. So your main line of defense needs to be the close() function.
See my answer Why would you ever implement finalize()?
This cannot be done with Java -- it needs a reference-counting garbage collector as far as I can tell. Have you considered opening and closing your object's physical data file as needed, rather than keeping it open for the lifetime of the object?
You could override finalize() in your object, but that is problematic for reasons others have mentioned.
For your specific example, you could take a look at using something like File.deleteOnExit(), which would remove the file once the VM exits.