Keeping track of instantiated objects

G

gooch

I am a software engineer who has used C an C++ in the past and I am
currently learning Java. I have been doing some reading and see that
the finalize function of Java operates as the destuctor in C++. I also
have read that the finalize function is not called until garbage
collection occurs. Now you can use the System.gc() call to attempt to
force garbage collection but from everything I have read you are never
guaranteed that garbage collection will occur.

My question then is what do you do if you need to maintain a count of
the number of objects of a class that are instantiated. In C++ I would
normally use a static class variable to hold a count and increment it
on construction and decrement it on destruction. It seems to me that
given what I said in the first paragraph this is not necessarily going
to always give you the correct value. Is there something is paragraph
one that I have misunderstood or would you handle this in some other
way in Java. Thanks.
 
S

Stefan Schulz

I am a software engineer who has used C an C++ in the past and I am
currently learning Java. I have been doing some reading and see that
the finalize function of Java operates as the destuctor in C++. I also
have read that the finalize function is not called until garbage
collection occurs. Now you can use the System.gc() call to attempt to
force garbage collection but from everything I have read you are never
guaranteed that garbage collection will occur.

You usually should not use finalize(). It is for those rare cases when
you actually need significant work to reclaim an object, most often in
conjunction with using non-java allocated resources via JNI. Liberal use
of finalize() significantly hinders a good, clean garbage collecting,
since all Objects that define a finalize() method will usually be
collected only when there is absolutely no other way to free up space,
since finalize() can take arbitrarily long, and even revive a previously
unreachable object.
My question then is what do you do if you need to maintain a count of
the number of objects of a class that are instantiated. In C++ I would
normally use a static class variable to hold a count and increment it
on construction and decrement it on destruction. It seems to me that
given what I said in the first paragraph this is not necessarily going
to always give you the correct value. Is there something is paragraph
one that I have misunderstood or would you handle this in some other
way in Java. Thanks.

I think you still live a little too much in C-Land ;) If you _really_
need instance counting (which you usually don't once you learn to love
the Garbage Collector), you should add explicit destruction to your
Objects, for example a dispose() method.
 
W

William Brogden

I am a software engineer who has used C an C++ in the past and I am
currently learning Java. I have been doing some reading and see that
the finalize function of Java operates as the destuctor in C++. I also
have read that the finalize function is not called until garbage
collection occurs. Now you can use the System.gc() call to attempt to
force garbage collection but from everything I have read you are never
guaranteed that garbage collection will occur.

My question then is what do you do if you need to maintain a count of
the number of objects of a class that are instantiated. In C++ I would
normally use a static class variable to hold a count and increment it
on construction and decrement it on destruction. It seems to me that
given what I said in the first paragraph this is not necessarily going
to always give you the correct value. Is there something is paragraph
one that I have misunderstood or would you handle this in some other
way in Java. Thanks.

That might be a job for an Object pool - in which a single object has
the primary responsibility of maintaining the pool and other objects
essentially "lease" one when they need it and "release" it when done.
Typically used for database connections.

Bill
 
A

Andrew McDonagh

finalizers are not the same as destructors.
You usually should not use finalize(). It is for those rare cases when
you actually need significant work to reclaim an object, most often in
conjunction with using non-java allocated resources via JNI. Liberal use
of finalize() significantly hinders a good, clean garbage collecting,
since all Objects that define a finalize() method will usually be
collected only when there is absolutely no other way to free up space,
since finalize() can take arbitrarily long, and even revive a previously
unreachable object.




I think you still live a little too much in C-Land ;) If you _really_
need instance counting (which you usually don't once you learn to love
the Garbage Collector), you should add explicit destruction to your
Objects, for example a dispose() method.

I have to echo Stefan's points here and add that you shouldn't really
need to know how many instances you have. Its certainly rare in an OO
design to keep track of the number of instances of a class, regardless
of whether you have garbage collectors or not.

If you could post a description of your current design and why you need
to count the instances, I'm sure we could help remove this need.

However, given that you say you do need this design, then in a language
without destructors, I would an AbstractFactory pattern. The factory
would be responsible for creating and keeping track of the number its
created. Obviously it would need a 'remove', 'dispose', 'recycle' kind
of method to aid in the tracking.

By using a factory to create the objects, then it does not matter
whether other references to those objects are nulled, the factory would
always have a reference the the objects, ensuring they are not garbage
collected until they are removed from factory.

I would go as far as making the class to be counted having a package
level constructor so that only the factory can actually call it. Thereby
preventing any old sod from creating instances which are not tracked.

Obviously, this is not fool-proof as anyone can create another class in
the same package, and therefore have access to these constructors, but
you'd just have to trust your team not to do that.
 
G

gooch

You usually should not use finalize(). It is for those rare cases when
you actually need significant work to reclaim an object, most often in
conjunction with using non-java allocated resources via JNI. Liberal use
of finalize() significantly hinders a good, clean garbage collecting,
since all Objects that define a finalize() method will usually be
collected only when there is absolutely no other way to free up space,
since finalize() can take arbitrarily long, and even revive a previously
unreachable object.

So are you saying that objects that have a finalize function are
handled differently by the garbage collector than those that don't. I
did read that finalize functions are rarely used in Java but there was
no real explanation of why.
 
G

gooch

I have to echo Stefan's points here and add that you shouldn't really
need to know how many instances you have. Its certainly rare in an OO
design to keep track of the number of instances of a class, regardless
of whether you have garbage collectors or not.

Given your comments I would agree that the job of maintaining the
number of instances of a class belongs in a class other than the class
being counted. Thanks for the explanation, I am fairly new to real OO
programming even though I have used C++.
 
S

Stefan Schulz

So are you saying that objects that have a finalize function are
handled differently by the garbage collector than those that don't. I
did read that finalize functions are rarely used in Java but there was
no real explanation of why.

Yes, Objects that define a finalize() method are in almost all
implementations of the JVM second class citizens when it comes to
garbage collection. A normal Object can be reclaimed very quickly and
with little hassle: Just mark the space it occupied as free once more.
An Object that defines finalize, however, needs special treatment, with
a lot of extra checks and hops to jump through. Since this is a rather
large cost in time, at a very awkward moment (during a full GC, the rest
of the JVM is brought to a standstill!) it is only done when it
absolutely must be done. That is, when all other reclaimable objects
have been reclaimed, and there is still not enough space available.
 
R

Ryan Stewart

Stefan Schulz said:
On 9 Jan 2005 15:31:27 -0800
Yes, Objects that define a finalize() method are in almost all
implementations of the JVM second class citizens when it comes to
garbage collection.
Not that I don't believe you, but do you have a good reference for this? I've
never heard anything along those lines.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top