Chapter 17 Garbage Collection and Memory

1) The Java virtual machine uses a technique known as garbage collection to determine when an object is no longer referenced within a program, and so can be safely reclaimed to free up memory space.

  In simple terms, when an object is no longer reachable from any executable code, the space it occupies can be reclaimed. We use the phrase "can be" because space is reclaimed at the garbage collector's discretion, usually only if more space is needed or if the collector wants to avoid running out of memory. A program may exit without running out of space or even coming close and so may never need to perform garbage collection. An object is "no longer reachable" when no reference to the object exists in any variable of any currently executing method, nor can a reference to the object be found by starting from such variables and then following each field or array element, and so on.

 

2) Mark-and-sweep Garbage Collection Model:

  The simplest model of garbage collection not subject to this problem is called mark-and-sweep. The name refers to the way the two phases of garbage collection are implemented. To find which objects are live, the garbage collector first determines a set of roots that contains the directly reachable objects: References in local variables on the stack, for example, are reachable because you can use those variables to manipulate the object. Objects referred to by local variables are therefore clearly live.

  Once a set of roots is determined, the collector will mark the objects referenced by those roots as reachable. It will then examine references in each of those objects. If an object referred to by such a reference is already marked reachable from the first step, it is ignored. Otherwise. the object is marked reachable and its references are examined. This process continues until no more reachable objects remain unmarked. After this marking process is complete, the collector can reclaim the dead objects (those which are not marked) by sweeping them away.

 

3) A class can implement a finalize method that is executed before an object's space is reclaimed to give you a chance to use the state contained in the object to reclaim other non-memory resources. The finalize method is declared in the Object class:

protected void finalize() throws Throwable

Is invoked by the garbage collector after it determines that this object is no longer reachable and its space is to be reclaimed. This method might clean up any non-memory resources used by this object. It is invoked at most once per object, even if execution of this method causes the object to become reachable again and later it becomes unreachable again. There is no guarantee, however, that finalize will be called in any specific time period; it may never be called at all. This method is declared to throw any exception but if an exception occurs it is ignored by the garbage collector. The virtual machine makes no guarantees about which thread will execute the finalize method of any given object, but it does guarantee that the thread will not hold any user-visible synchronization locks.

4) The Runtime class, together with some convenience methods in the System class, allows you to invoke the garbage collector, request that any pending finalizers be run, or query the current memory state:

public void gc()

Asks the virtual machine to expend effort toward recycling unused objects so that their memory can be reused.

public void runFinalization()

Asks the virtual machine to expend effort running the finalizers of objects that it has found to be unreachable but have not yet had their finalizers run.

public long freeMemory()

Returns an estimate of free bytes in system memory.

public long totalMemory()

Returns the total bytes in system memory.

public long maxMemory()

Returns the maximum amount of memory, in bytes, that the virtual machine will ever attempt to use. If there is no limit, Long.MAX_VALUE is returned. There is no method to set the maximum; a virtual machine will typically have a command-line or other configuration option to set the maximum.

To invoke these methods you need to obtain a reference to the current Runtime object via the static method Runtime.getRuntime. The System class supports static gc and runFinalization methods that invoke the corresponding methods on the current Runtime; in other words, System.gc() is equivalent to Runtime.getRuntime().gc().

 

java.lang.System

public final class System extends Object

The System class contains several useful class fields and methods. It cannot be instantiated.

Among the facilities provided by the System class are standard input, standard output, and error output streams; access to externally defined properties and environment variables; a means of loading files and libraries; and a utility method for quickly copying a portion of an array.

java.lang.Runtime

public class Runtime extends Object

Every Java application has a single instance of class Runtime that allows the application to interface with the environment in which the application is running. The current runtime can be obtained from the getRuntime method.

An application cannot create its own instance of this class.

5) You would like to be able to have a reference to an object that doesn't force the object to remain reachable if that is the only reference to the object. Such special references are provided by reference objects. A reference object is an object whose sole purpose is to maintain a reference to another object, called the referent.

The classes for the reference object types are contained in the package java.lang.ref. The primary class is the generic, abstract class Reference<T>, which is the superclass of all the specific reference classes. It has four methods:

public T get()

Returns this reference object's referent object.

public void clear()

Clears this reference object so it has no referent object.

public boolean enqueue()

Adds this reference object to the reference queue with which it is registered, if any. Returns TRue if the reference object was enqueued and false if there is no registered queue or this reference object was already enqueued.

public boolean isEnqueued()

Returns true if this reference object has been enqueued (either by the programmer or the garbage collector), and false otherwise.

  In decreasing order of strength, the kinds of reference objects available to you are SoftReference<T>, WeakReference<T>, and PhantomReference<T>. These correspond to the reachability stages an object can pass through:

  • An object is strongly reachable if it can be reached through at least one chain of strong references (the normal kind of references).

  • An object is softly reachable if it is not strongly reachable, but is reachable through at least one chain containing a soft reference.

  • An object is weakly reachable if it is not softly reachable, but is reachable through at least one chain containing a weak reference.

  • An object is phantom reachable when it is not weakly reachable, has been finalized (if necessary), but is reachable through at least one chain containing a phantom reference.

  • Finally, an object is unreachable if it is not reachable through any chain.

  Once an object becomes weakly reachable (or less), it can be finalized. If after finalization the object is unreachable, it can be reclaimed.

  Objects need not actually go through all these stages. For example, an object that is reachable only through strong references becomes unreachable when it is no longer strongly reachable.

  The reachability stages of an object trigger behavior in the garbage collector appropriate to the corresponding reference object types:

  • A softly reachable object may be reclaimed at the discretion of the garbage collector. If memory is low, the collector may clear a SoftReference object so that its referent can be reclaimed. There are no specific rules for the order in which this is done (but a good implementation will prefer keeping recently used or created references, where "used" is defined as "invoked get"). You can be sure that all SoftReferences to softly reachable objects will be cleared before an OutOfMemoryError is thrown.

  • A weakly reachable object will be reclaimed by the garbage collector. When the garbage collector determines that an object is weakly reachable, all WeakReference objects that refer to that object will be cleared. The object then becomes finalizable and after finalization will be reclaimed (assuming it is not resurrected) unless it is phantom reachable.

  • A phantom reachable object isn't really reachable in the normal sense because the referent object cannot be accessed via a PhantomReferenceget always returns null. But the existence of the phantom reference prevents the object from being reclaimed until the phantom reference is explicitly cleared. Phantom references allow you to deal with objects whose finalize methods have been invoked and so can safely be considered "dead." Phantom references are used in conjunction with the reference queues we discuss in the next section.

  Both SoftReference and WeakReference declare a constructor that takes a single referent object. All three classes declare a two-argument constructor that takes a referent object and a ReferenceQueue.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章