The C language was used to write the Unix operating system and other system-level routine. The most important rule in system programming is that every program has to clean up after itself. Whatever storage is allocated must be freed. Whatever handles are obtained must be released.
It is a major psychological change for a system programmer to learn an application language like Java. Not only is it unnecessary to clean up after yourself, it is illegal to do so. There is no statement in Java to free storage. The Java environment uses garbage collection.
There idea of garbage collection took hold with the LISP language, and has been used in other environments descending from it. In particular, the Adobe PostScript printer language is an example of a major application based on a garbage collected language. The programming needed to support this approach is well known and was adapted by the developers of Java.
The basic idea is that an object keeps track of the number of reference variables that point to it. Consider the following:
When the assignment statement is executed, the variables xxx and yyy may contain references to any object of any type (or they may contain the value null). The assignment statement will copy the reference value in yyy to xxx, so that after the assignment both variables will designate the same object. When executing this statement, the Java language will first check xxx. If xxx does not contain null, Java reduces the count of the number of references in the object that xxx designates. The value in yyy is then copied to xxx. If this value is not null, then Java increases the count of references in the object that yyy designates.
The reference to an object is created by the new operation when the object is created. It has to be saved somewhere for the object to remain useful in subsequent statements. There is no way to find an object unless the reference is stored somewhere. So when the count of references to an object goes to zero, the object is no longer useful to the program and can be deleted.
Exactly when an object is actually deleted is up to the Java language. Periodically, the garbage collection component of the interpreter sweeps through the objects freeing storage occupied by objects that are no longer referenced. An object can have a special method called a destructor (the opposite of a constructor) than is called to help clean up as the object is about to be deleted. Destructors can help to close files, shutdown network sessions, or handle other side effects of object deletion.
To use Java correctly, a programmer must be relatively careless about creating and deleting objects. One must assume that garbage collection is so efficient that it can be taken for granted.
Most Java language classes, including String, Integer, and the other wrapper classes, do not allow the value of an object to change after the object has been allocated. When a program needs to edit a string, it will directly or indirectly create a new String object whose content is the new string value. The old String object will generally end up with a zero reference count and will be cleaned up in the next cycle of garbage collection.
Several decades of experience have shown that one of the more common programming errors is for one part of a program to delete an object that some other part of the program is still using. Garbage collection ensures that this mistake cannot occur.
On smaller, simpler systems (such as a PostScript printer) the garbage collection is triggered when storage nearly fills up with old, unreferenced objects. This produces irregular performance when the application periodically has to pause for the cleanup. Java runs garbage collection under a low priority thread. This produces uniform responsiveness and eliminates most of the traditional objections to garbage collection.