A simple understanding of the Java garbage collection mechanism and the role of the Finalize method _java

Source: Internet
Author: User
Tags closure garbage collection

When the garbage collector wants to reclaim objects, you first call the Finalize method of the class (you can write the program to validate the conclusion), and the normal Java-written class does not need to overwrite this method, because object has implemented a default, unless we want to implement a special function (which It involves a lot of things, such as object space tree and so on.
But with classes written outside Java (such as the memory allocated by the jni,c++ new method), the garbage collector is not able to properly recycle these parts, so we need to override the default method for proper release and recovery of this part of the memory (for example, C + + requires delete).
In summary, Finalize is the equivalent of a destructor, which is the first method to invoke when the garbage collector reclaims an object. But because the Java garbage collection mechanism can automatically do these things for us, we usually do not need to manually release ourselves.

Sometimes when you undo an object, you need to do something. For example, if an object is processing a non-Java resource, such as a file handle or a window character font, then you should make sure that the resource is released before an object is undone. To handle this situation, Java provides a mechanism called closure (finalization). With this mechanism you can define special operations that are executed when an object is to be released by the garbage collector.
To add a closure to a class (finalizer), you simply define the Finalize () method. This method is invoked when Java reclaims an object of the class. In the Finalize () method, you specify the action that must be taken before an object is undone. Garbage collection runs periodically, checking that the object is no longer referenced by the running state or indirectly through other objects. The Java run system calls the Finalize () method of the object before the object is freed.

The general format for the Finalize () method is as follows:

protected void Finalize ()
{
//Finalization code here
}

Where the keyword protected is to prevent code access to the Finalize () identifier that is defined outside the class. The identifier and other identifiers are explained in chapter 7th.

It is important to understand that finalize () is invoked just before garbage collection. For example, when an object exceeds its scope, finalize () is not invoked. This means that you cannot know when--or even--finalize ()--is invoked. Therefore, your program should provide other ways to release the system resources used by the object, rather than finalize () to complete the normal operation of the program.

Note: If you are familiar with C + +, you know that C + + allows you to define an undo function (destructor) for a class that is invoked before the object is just out of scope. Java does not support this idea nor does it provide undo functions. The Finalize () method is only close to the function of the undo function. When you have extensive experience with Java, you will see that because Java uses the garbage collection subsystem, it is almost unnecessary to use undo functions.


Finalize works like this: Once the garbage collector is ready to release the storage space occupied by the object, it first calls Finalize (), and the object's memory is only really reclaimed during the next garbage collection. So if you use Finalize (), Some important cleanup or clean-up work can be done during the garbage collection.

When is the Finalize () called?
There are three kinds of situations

    1. All objects are automatically invoked when garbage collection, such as when running System.GC ().
    2. Call the Finalize method once for each object when the program exits.
    3. Explicit call to Finalize method

In addition, normally, when an object is collected as useless information by the system, Finalize () is invoked automatically, but the JVM does not guarantee that finalize () must be invoked, that is, the call to finalize () is indeterminate. That's why sun doesn't advocate the use of Finalize ()

Sometimes when you undo an object, you need to do something. For example, if an object is processing a non-Java resource, such as a file handle or a window character font, then you should make sure that the resource is released before an object is undone. To handle this situation, Java provides a mechanism called closure (finalization). With this mechanism you can define special operations that are executed when an object is to be released by the garbage collector.

To add a closure to a class (finalizer), you simply define the Finalize () method. This method is invoked when Java reclaims an object of the class. In the Finalize () method, you specify the action that must be taken before an object is undone. Garbage collection runs periodically, checking that the object is no longer referenced by the running state or indirectly through other objects. The Java run system calls the Finalize () method of the object before the object is freed.

The general format for the Finalize () method is as follows:

protected void Finalize ()
{
//Finalization code here
}

Where the keyword protected is to prevent code access to the Finalize () identifier that is defined outside the class. The identifier and other identifiers are explained in chapter 7th.

It is important to understand that finalize () is invoked just before garbage collection. For example, when an object exceeds its scope, finalize () is not invoked. This means that you cannot know when--or even--finalize ()--is invoked. Therefore, your program should provide other ways to release the system resources used by the object, rather than finalize () to complete the normal operation of the program.

Note: If you are familiar with C + +, you know that C + + allows you to define an undo function (destructor) for a class that is invoked before the object is just out of scope. Java does not support this idea nor does it provide undo functions. The Finalize () method is only close to the function of the undo function. When you have extensive experience with Java, you will see that because Java uses the garbage collection subsystem, it is almost unnecessary to use undo functions.

The garbage collector automatically calls the object's Finalize method when it is garbage collected, and is used for some user-defined, non-memory cleanup because the garbage collector does not handle anything other than memory. So, sometimes users need to define some cleanup methods, such as working with non-memory resources such as files and ports.

GC Overview of 1.JVM
  
The GC, or garbage collection mechanism, is the memory that the JVM uses to free objects that are no longer in use. The Java language does not require the JVM to have a GC, nor does it specify how the GC works. However, the common JVM has a GC, and most GC uses a similar algorithm to manage memory and perform collection operations.
  
After fully understanding the garbage collection algorithm and the execution process, can effectively optimize its performance. Some garbage collection is dedicated to special applications. For example, live applications are primarily designed to avoid garbage collection outages, while most OLTP applications focus on overall efficiency. By understanding the workload of the application and the garbage collection algorithm supported by the JVM, you can configure the garbage collector optimally.
  
The purpose of garbage collection is to clear objects that are no longer in use. GC Determines whether an object is collected by determining whether it is referenced by the active object. The GC first has to determine whether the object is time to collect. Two common methods are reference counts and object reference traversal.
  
1.1. Reference count
  
A reference count stores all the references to a particular object, that is, when an application creates a reference and the reference is out of range, the JVM must appropriately increase or decrease the number of references. When an object has a reference number of 0 o'clock, garbage collection can be done.
  
1.2. Object reference traversal
  
The early JVM used reference counting, and now most JVMs use object reference traversal. Object reference traversal determines the reachable (reachable) object, starting with a set of objects, and following each link along the entire object graph. If an object cannot arrive from one of these root objects (at least one), it is collected as garbage. In the object traversal phase, the GC must remember which objects are reachable so that the unreachable object is deleted, which is called a tag (marking) object.
  
Next, the GC removes unreachable objects. When deleted, some GC is just a simple scan stack, removing unmarked unmarked objects and freeing their memory to generate new objects, called scavenging (sweeping). The problem with this approach is that the memory is divided into small segments that are not sufficient for new objects, but are large in combination. As a result, many GC can rearrange objects in memory and compress (compact) to form available space.
  
To this end, the GC needs to stop other activity activities. This approach means that all application-related work stops and only the GC runs. As a result, many promiscuous requests were added or subtracted during the response. In addition, more complex GC increases or runs at the same time to reduce or eliminate application interruptions. Some GC use single-threaded to complete this work, while others use multithreading to increase efficiency.
  
2. Several garbage collection mechanisms
  
2.1. Mark-Clear Collector
  
This collector first iterates through the object graph and marks the reachable objects, and then scans the stack for unmarked objects and frees their memory. This collector typically uses single-threaded work and stops other operations.
  
2.2. Mark-Compress collector
  
Sometimes also called Mark-purge-compression collectors, which have the same mark stage as the tag-purge collector. In the second phase, the tagged object is copied to the new domain of the stack to compress the stack. This collector also stops other operations.
  
2.3. Replication Collector
  
This collector divides the stack into two domains, often called a half space. Using only half of the space each time, the new object generated by the JVM is placed in the other half of the space. When the GC runs, it compresses the stack by copying the reachable objects to the other half of the space. This approach applies to objects with short lifetimes, and continuous replication of long lifetime objects results in reduced efficiency.
  
2.4. Incremental collector
  
The incremental collector divides the stack into domains, collecting garbage from only one domain at a time. This can cause a smaller application outage.
  
2.5. Generational Collectors
  
This collector divides the stack into two or more domains for storing objects of different lifetimes. New objects generated by the JVM are generally placed in one of the domains. Over time, the objects that continue to exist will get the usage period and go into a longer lifetime domain. The generational collector uses different algorithms for different domains to optimize performance.
  
2.6. Concurrent Collectors
  
The concurrent collector runs concurrently with the application. These collectors generally have to stop other operations at some point, such as compression, to complete a specific task, but because other applications can do other background operations, the actual time to interrupt other processing is greatly reduced.
  
2.7. Parallel collector
  
Parallel collectors use some traditional algorithms and use multithreading to perform their work in parallel. Using multithreading on multiple-CPU machines can significantly improve the scalability of Java applications.

3. The destruction process of the object

In the process of object destruction, according to the implementation of the object's finalize, can be divided into the following categories, the system will record the corresponding state of the object:
Unfinalized does not execute finalize and the system is not ready to execute.
Finalizable can execute finalize, and the system will execute finalize at a later time.
Finalized the object's finalize has been executed.

How does GC keep track of Finalizable objects? GC has a queue called F-queue, where all objects join the queue when they become finalizable, and then wait for the GC to execute its Finalize method.

At this point we introduced another record classification of objects, and the system can check which one object belongs to.
Reachable an object that can be reached from the active object reference chain. Includes local variables for all threads on the current stack, all static variables, and so on.
Finalizer-reachable except reachable, objects that can be reached by reference from F-queue.
Unreachable the other objects.

Look at the state transition diagram of the object.

So big, so dizzy, look slowly.

1 First, all the objects are from reachable+unfinalized to the road of death.

2 when the object is unreachable from the current active set, the object can be changed from the reachable state to the f-reachable or unreachable state.

3 When the object is reachable+unfinalized, the GC moves it into the f-queue, and the state changes to f-reachable+finalizable.

4 OK, the key is coming, at any time, GC can get a Finalizable object from F-queue, mark it as finalized, and then execute its Finalize method, because the object is reachable in this thread, The object then becomes reachable (and finalized). When the Finalize method executes, it is possible to turn other f-reachable objects into a reachable, which is called object regeneration.

5 When an object is unreachable+unfinalized, if the object uses the default object's finalize, or if it is overridden, the new implementation does nothing. For performance, GC can change the object to reclaimed state directly, without adding to the f-queue waiting for GC to do further processing.

6 see from the state diagram, no matter how toss, any object's finalize only executes at most once, once the object becomes finalized, how will not go back to f-queue. Of course, there is no chance to execute finalize again.

7 when an object is unreachable+finalized, the object is not far away from the real death. The GC can safely reclaim the object's memory. into the reclaimed.


An example of an object rebirth

Class C { 
  static A; 
} 
 
Class A { 
  b b; 
 
  Public A (b b) { 
    this.b = b; 
  } 
 
  @Override public 
  Void Finalize () { 
    System.out.println ("A finalize"); 
    C.A = this; 
  } 
 
Class B { 
  String name; 
  int age; 
 
  Public B (String name, int age) { 
    this.name = name; 
    This.age = age; 
  } 
 
  @Override public 
  Void Finalize () { 
    System.out.println ("B finalize"); 
 
  @Override public 
  String toString () {return 
    name + ' is ' + age; 
  } 
} 
 
public class Main {public 
  static void Main (string[] args) throws Exception { 
    A A = new A (New B ("Allen"); 
   a = null; 
 
    System.GC (); 
    Thread.Sleep (5000); 
    System.out.println (C.A.B); 
  } 
 

Expected output

A Finalize 
B- 
Allen is 20 

But it is possible to fail, due to the uncertainty of GC and the timing problem, and a few more runs should be successful. Detailed explanation see the reference document at the end of the article.

3.1 Finalize order of execution of objects

The finalize execution of all finalizable objects is indeterminate, not determining which thread is executing or the order of execution.
Consider the following situation to see why, the instance a,b,c is a set of finalizable objects that are circularly referenced by each other.

3.2 When and how to use Finalize

From the above analysis, to draw a conclusion.
(1) Most importantly, try not to use finalize, too complex, or let the system care better. Other methods can be defined to free a non-memory resource.
(2) If used, try to be as simple as possible.
(3) If used, to avoid the regeneration of the object, this is to find their own trouble.
(4) can be used to protect non-memory resources from being freed. Even if we define other methods to free a non-memory resource, others may not invoke the method to release it. In finalize it can be checked, if not released to release the Good, late release is better than not release.
(5) The object is not guaranteed to be destroyed even if the object's finalize has been run. To implement some of the actions to ensure that objects are completely destroyed, you can only rely on the class and GC interactions within the JAVA.LANG.REF.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.