Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

dispose() and the garbage collector

Status
Not open for further replies.

aka922

Programmer
Sep 19, 2011
15
0
0
AU
I have a class that encapsulates a Container, say Set, and I want the method getSet to return a *copy* of the data member (so as to preserving the privacy of access to the data member).

However, this method is accessed many times by the GUI interface, almost on every user driven event. What I want to know is this:

For the temporary objects returned (to display the collection but not allow direct modification) does invoking dispose() on these temporary objects support garbage collection or not?

Obviously I don't want to dispose of the objects within the collection, only to preserve its integrety within the class.
 
Hi Aka,

If you fully clone the Set by doing a deep copy, then you will have no problems. Once the container Set no longer has any references, it will be eligible for GC. Since all the elements of the Set are clones of the original elements, they will be GC'd too as the only references to them should be from the GC'd Set.

However, you mentioned dispose(). This is usually used when allocating native resources. i.e. with AWT or Sockets. I am assuming that you don't have native resources within the Set. Is this correct?

Cheers,
Scott



 
Thank you Geeky.

Interestingly, I do not want to clone the collection; rather I do want the contained objects to be available for messages from the GUI (ie for real time interaction).

I have also wondered whether clear() on the returned copy (after its usage as a temporary) would shrink the memory allocation down to a size the is negligible.

In another world, these temporary objects would be called pointer arrays - and a lot of them are being created "new",

Yrs, Jim.
 
Hi Jim,

Sorry - I misread your first post. When I saw the word Set, I immediately thought Collection, but you said Container.

Ok - so I gather the elements really are AWT Components. In that case, calling dispose() on them is going to release their native resources below. This will mean they will no longer be displayed until you either pack() or show() them again. This will not however release the Java resources until they are no longer referenced. I think this is not what you want.

Can you post an example of how you are creating the Set within getSet()? Nothing beats the code when it comes to explaining. From what you have said in the second post it seems you are just creating a bunch of references to AWT Containers, but it would be nice to be sure, as you also state a copy is returned in the first post.

Also you mention the clear() method. I am not familiar with this on AWT components, which makes me think I may have completely misunderstood your question all together.

Cheers,
Scott
 
Thanks for that Scott,

You have reminded me jus how important it is to get one's jargon right. Yes I did mean Collection and not a Container. I want the AWT/Swing components to display, and have direct access to every element "aggregated" by the current object (like in a graph).

What I do not want is to allow client code to have direct access to the Collection itself - risks corrupting the structure itself.

Hence a copy of the Collection (eg Set) is returned by getSet so preserving the "encapsulation" of the relations between objects.

Sorry if this still sounds confused, Jim.
 
Further to previous...

Rather than code I would prefer to send you the design specs.

Eventually the GUI will perform two sorts of topological analysis on this relational structure: (acyclic) transitive closure and various unions of equvalence classes - with all resilts returned as Collections (eg Lists) according to the current state of the structure.

I hope you can see that every structural change requires refreshing the GUI based on a new temporary Collection object.

Smiles, Jim.
 
Please forgive me everyone,

It is the finalize() method and not dispose() that I was curious about - ie when is it worth calling finalize() on a temporary.

Since I don't know how to close a discussion thread in this forum let's just say - woopse my mistake.

Jim.
 
Hi Jim,

No worries. If you still require an answer, the answer is hardly ever, unless you have some very interesting settings in your JVM's memory parameters. This is because if the objects are short lived, they will probably not survive the Eden space in the young generation anyway.

If you are concerned about this, or just want to see the behaviour anyway, I would recommend you run jconsole against your application. It shows usage in all the memory spaces over time and is an extremely useful tool for memory tuning.

Cheers,
Scott
 
One final comment. finalize() is protected in recent versions of java, so you cannot call it without resorting to reflection anyway. Also, it's usually only implemented on classes that allocate native system resources outside the JVM, such as Sockets or AWT UI components, otherwise it does nothing as it's still the job of the Garbage Collector to free the space in the JVM pool. In the example you have above, it's just the Container class and the Entry classes for each element added to the container that will be allocated. i.e. if you had the Set implemented via a LinkedHashSet, then you would have one instance of the java.util.LinkedHashSet and as many instances of java.util.Map.Entry as you had elements within the set. All this would be allocated in the JVM memory, so calling finalize() on the Container would not do anything (I just checked the Java source tree to make sure and it's not defined in any of the Container classes, abstract, implementation or otherwise). If you did call finalize() on the elements within the Set, this could call dispose() if they are AWT components, you would need to look at the java source for the objects in question to be sure.

All in all, you should stay clear of finalize() directly, as there are usually more appropriate methods to call. I usually do call clear() or removeAll() on my collections before they get de-referenced. I believe this is not necessary, since de-referencing the collection will also de-reference the Entry objects, but old coding habits die hard.


Cheers,
Scott
 
My advice: unless you find serious memory or CPU problems, my experience tells me that dealing with GC is worthless. The performance gain is most cases is very little and will depend on the GC strategy, the JVM vendor and version, the OS and so on.

Cheers,
Dian
 
Thanks to all,

My reading of the API has Object.finalise() as recording a notification on exactly one thread - which could only support the GC in a multi-threaded environment.

Note that any object that inherits from Object (ie all objects except arrays) can call the protected method - but ordinarily it is the GC itself that makes the call.

I do not think that shared references are at risk... because they have not been finalized - so if the GC decides it is time to run (in its own thread) only shallow copy reference allocations would be recovered.

Once again, perhaps it's time to end this discourse as either too difficult or too obscure, Jim.
 
Sorry Scott,

Once again you are mostly right - protected methods can only be called by another method in the class definition thus indirectly allowing public access (again sounds like a very bad practice).

We also note that protected methods such as clone() can be promoted to public in an override.

Forgive me, I've been looking into structures wherein shallow copy is essential for so long I'm forgetting all the rules.

In fact, I've never had a problem in Java coding where a deep copy is required.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top