In general, Reference Counting has the weakness of "it can't detect loops." However, in some cases, Reference Counting is really useful:
class EmergencyPatient {
DoctorPtr doctor;
EmergencyPatient() { doctor = Doctor::acquire(); }
~EmergencyPatient() { Doctor::release(doctor); }
};
Now, in a reference counted world, as soon as we no longer refer to an EmergencyPatient, the doctor is released.
In Java's non-refcounted world, this depends largely on when the EmergencyPatient is garbage collected -- and since the garbage collector is generational, the EmergencyPatient can be in an older generation, and not collected for a long time.
To me, a doctor is a very precious resource; other EmergencyPatient need doctors. However, to Java, the EmergencyPatient object is just a few bytes of memory.
What is the right way to solve this problem? (There are some resources that I want to be freed as soon as I know they're no longer being used).
Thanks!
The right way to solve this, within the Java framework, is to use a try-finally construct:
Doctor doctor = doctorFactory.acquire();
try
{
EmergencyPatient patient = new EmergencyPatient(doctor);
doctor.examinePatient();
}
finally
{
doctor.release();
}
You'll notice, by the way, that in my implementation (as in the real world!), the patient does not pick the doctor. This enables you to provide mock doctors to the patient in your unit tests.
Edit: moving away from manufactured classes, this is the structure that you should be using for every java.sql.Connection, every java.io.InputStream, or any other object that manages non-memory resources.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With