Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Garbage collection in Java

Exposition:

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.

Problem:

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.

Question:

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!

like image 354
anon Avatar asked Apr 25 '26 08:04

anon


1 Answers

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.

like image 111
kdgregory Avatar answered Apr 27 '26 22:04

kdgregory