Subject:   Java; I want a destructor!
Date:   2006-01-23 23:26:01
From:   bastos
Response to: Java; I want a destructor!

This is a total falsehood. Destructors in a garbage collected langauge are quite easy indeed. Since telling when memory is ready to be freed up is simply a matter of keeping, and checking, a reference count for that object...calling destructors are obviously simply handled at this point. Is an object being referenced (in use)? No, then lets destroy it, wait, it has a destructor, let's call that first...

This is why Java *does* give you a destructor. Java destructors however have a problem, and this problem is called by java optimizations. Some of these optimizations are that Java doesn't collect immediately. And java doesn't collect immediately due to the fact that it's not always effective to do so, such as if a bunch of objects were just fell out of reference because a program is about to exit, obviously we'd be freeing them up for nothing in most platforms as they'll get cleaned up by the process ending.

Also, since java allocates its memory in blocks, it will wait until a threshold is met before it garbage collects what has no reference rather than allocating more memory. This is another one of the many optimizations that has sped java up over the years.

Below is a simple program, running it and analyzing the output will demonstrate the behavior described above, and set the record straight about java having a destructor:

import java.util.LinkedList;

class TestGC {
static int lastid = 0;

class MemSucker {
public int id = 0;

byte[] Suck = new byte[25000];
id = ++lastid;
System.out.printf("memsucker %d created...\n", id);

protected void finalize () {
System.out.printf("memsucker %d destroyed...\n", id);

TestGC () {
LinkedList <MemSucker> sucklist = new LinkedList <MemSucker> ();

for (int i = 0; i < 5000; i++) {
sucklist.add(new MemSucker ());

if (i % 2 == 0) {
int id = sucklist.removeFirst().id;
System.out.printf("marked %d for GC\n", id);

public static void main (String[] arguments) {
new TestGC ();