Explanation of java garbage collection and Memory leakage

Source: Internet
Author: User

1. Core Idea of the garbage collection Algorithm
The Java language sets up a garbage collection mechanism to track the objects in use and discover and recycle objects that are no longer used (referenced. This mechanism can effectively prevent two risks that may occur in dynamic memory allocation: Memory depletion caused by excessive memory spam and illegal Memory Reference caused by improper memory release.
The core idea of the garbage collection algorithm is to identify the available memory space of the virtual machine, that is, the objects in the heap space. If the object is being referenced, it is called a surviving object. Otherwise, if an object is no longer referenced, It is a spam object and the occupied space can be reclaimed for redistribution. The selection of the garbage collection algorithm and the reasonable adjustment of the garbage collection system parameters directly affect the system performance. Therefore, developers need to have a deeper understanding.
 
2. Conditions for triggering the master GC (Garbage Collector)
The frequency of jvm gc is very high, but this GC takes a very short time, so it has little impact on the system. It is worth noting that the trigger condition of the main GC is obvious to the system. In general, there are two conditions that will trigger the main GC:
① When the application is idle, that is, when no application thread is running, GC will be called. GC is performed in the thread with the lowest priority, so when the application is busy, the GC thread will not be called, except for the following conditions.
② When the Java heap memory is insufficient, GC will be called. When the application thread is running and a new object is created during running, if the memory space is insufficient, JVM will forcibly call the GC thread to recycle the memory for new allocation. If the GC does not meet the memory allocation requirements after one time, the JVM will perform two further GC attempts. If the GC fails to meet the requirements, the JVM reports an error of "out of memory" and the Java application stops.
The JVM determines whether to perform the primary GC based on the system environment, and the system environment is constantly changing. Therefore, the operation of the primary GC is uncertain and cannot be predicted when it will inevitably emerge, however, it can be determined that the main GC is repeated for a long-running application.
 
3. Measures to Reduce GC overhead
According to the above GC mechanism, program running will directly affect the changes in the system environment, thus affecting GC triggering. If the GC features are not designed and encoded, a series of negative effects such as memory resident will occur. To avoid these impacts, the basic principle is to minimize garbage and reduce GC overhead. Specific measures include the following:
(1) do not explicitly call System. gc ()
The JVM is recommended to perform primary GC for this function. Although it is only recommended, it will trigger the primary GC in many cases to increase the frequency of primary GC, this increases the number of intermittent pauses.
 
(2) minimize the use of temporary objects
After a function call is called, the temporary object will become garbage. Using less temporary variables is equivalent to reducing the generation of garbage, thus increasing the time for the second trigger condition, reduces the chance of main GC.
 
(3) it is best to explicitly set the object to Null when it is not used.
Generally, Null objects are treated as garbage. Therefore, explicitly setting unused objects to Null is helpful for GC collectors to identify garbage and improve GC efficiency.
 
(4) Try to use StringBuffer instead of String to accumulate the String (For details, refer to the String and StringBuffer in another blog article in JAVA)
Because String is a fixed-length String object, when adding a String object, it is not expanded in a String object, but a new String object is created, for example, if Str5 = Str1 + Str2 + Str3 + Str4, multiple spam objects are generated during the execution of this statement, because a new String object must be created during the "+" operation, however, these transition objects have no practical significance for the system and only increase more garbage. To avoid this situation, you can use StringBuffer to accumulate strings. Because StringBuffer is variable-length, it is expanded based on the original, without generating intermediate objects.
 
(5) You can use basic types such as Int and Long to remove Integer and Long objects.
The memory resources occupied by the basic type variables are much less than those occupied by the corresponding objects. If not necessary, it is best to use the basic variables.
 
(6) Use as few static object variables as possible
Static variables are global variables and will not be recycled by GC. They will continue to occupy the memory.
 
(7) time when the dispersed object was created or deleted
When a large number of new objects are created in a short period of time, especially large objects, a large amount of memory is suddenly required. In this case, the JVM can only perform primary GC, to recycle memory or integrate memory fragments to increase the frequency of the primary GC. The same applies to deleting objects in a centralized manner. It causes a large number of spam objects to suddenly appear, and the free space is inevitably reduced, which greatly increases the chance to force the main GC when the next object is created.
 
4. gc and finalize Methods
(1) gc method for garbage collection
Using System. gc () can request Java garbage collection regardless of the garbage collection algorithm used by JVM. It should be noted that calling System. gc () is only a request. After JVM accepts the message, it does not immediately perform garbage collection, but only weighted several garbage collection algorithms to make garbage collection easy or happen early, or there are many recycles.
 
(2) finalize method: view the running of the Garbage Collector
Before the JVM Garbage Collector collects an object, it is generally required that the program call an appropriate method to release the resource, but without explicitly releasing the resource, java provides a default mechanism to terminate the release of resources for this object. This method is finalize (). Its prototype is:
Protected void finalize () throws Throwable
After the finalize () method returns, the object disappears and the garbage collection starts to be executed. Throws Throwable in the prototype indicates that it can throw any type of exception.
Therefore, when an object is about to be destroyed, some aftercare work is required. You can write these operations in the finalize () method.
Protected void finalize ()
{
// Finalization code here
}
 
(3) Sample Code
 
Class Garbage
{
Int index;
Static int count;
Garbage ()
{
Count ++;
System. out. println ("object" + count + "construct ");
SetID (count );
}

Void setID (int id)
{
Index = id;
}

Protected void finalize () // rewrite the finalize method
{
System. out. println ("object" + index + "is reclaimed ");
}

Public static void main (String [] args)
{
New Garbage ();
New Garbage ();
New Garbage ();
New Garbage ();
System. gc (); // request to run the Garbage Collector
}
}
 
5. Java Memory leakage
Because of the garbage collection mechanism, any inaccessible object (the object is no longer referenced) can be recycled by the garbage collection thread. Therefore, the Java Memory leakage usually refers to unintentional or unintentional object reference or unintentional Object persistence. The unintentional Object Reference refers to the fact that the Code developer has already used the object, however, the reference to this object is accidentally saved due to an Encoding Error (this reference is not the subjective intention of the coders ), this prevents the object from being recycled by the garbage collector. the space that was supposed to be released but ultimately not released can be considered as "leaked ".
Consider the following program. In the ObjStack class, use the push and pop methods to manage objects in the stack. The indexes in the two methods are used to indicate the next available position in the stack. The push method stores references to new objects and adds the index value. The pop method reduces the index value and returns the top element of the stack. In the main method, a stack with a capacity of 64 is created, and the push method is called 64 times to add objects to it. At this time, the index value is 64, and then the pop method is called 32 times, then the index value is changed to 32, indicating that the space in the stack should be collected. But in fact, the pop method only reduces the index value, and the stack still keeps references to those objects. Therefore, 32 useless objects will not be recycled by GC, resulting in Memory leakage.
 
Public class ObjStack {
Private Object [] stack;
Private int index;
ObjStack (int indexcount ){
Stack = new Object [indexcount];
Index = 0;
}
 
Public void push (Object obj ){
Stack [index] = obj;
Index ++;
}
Public Object pop (){
Index --;
Return stack [index];
}
}

Public class Pushpop {
Public static void main (String [] args ){
Int I = 0;
Object tempobj;
ObjStack stack1 = new ObjStack (64); // a new ObjStack object and calls a constructor with parameters. The size of the allocated stack Obj array is 64, and 64 objects can be stored, starting from 0.
While (I <64)
{
Tempobj = new Object (); // loops the new Obj Object and stores the objects of each loop in the stack Obj array one by one.
Stack1.push (tempobj );
I ++;
System. out. println ("no." + I + "sub-stack" + "/t ");
}
While (I> 32)
{
Tempobj = stack1.pop (); // space is wasted.
// The correct pop method can be changed to the following instructions. When the reference is returned, the stack deletes the reference to them, so the garbage collector can recycle them later.
/*
* Public Object pop () {index--; Object temp = stack [index]; stack [index] = null; return temp ;}
*/
I --;
System. out. println ("th" + (64-I) + "times out stack" + "/t ");
}
}
}

How to eliminate Memory leakage
Although Java Virtual Machine (JVM) and its garbage collector (garbage collector, GC) are responsible for managing most of the memory tasks, memory leakage may still occur in Java software programs. In fact, this is a common problem in large projects. The first step to avoid Memory leakage is to figure out how it happened. This article describes some common memory leak traps for writing Java code and some best practices for writing non-Leak Code. Once a memory leak occurs, it is very difficult to point out the code that causes the leak. Therefore, this article also introduces a new tool for diagnosing leaks and pointing out the root cause. This tool has very low overhead, so you can use it to find memory leaks in the production system.
Role of the Garbage Collector
Although the Garbage Collector handles most of the memory management issues, making it easier for programmers to live, programmers may still make mistakes and cause memory problems. In short, GC cyclically traces all references from "root" objects (stack objects, static objects, objects pointed to by JNI handles, and so on, and mark all objects it can reach as active. The program can only manipulate these objects. Other objects are deleted. Because GC makes it impossible for the program to reach the deleted object, it is safe to do so.
Although memory management can be said to be automated, it does not prevent programmers from thinking about memory management issues. For example, there will always be overhead for allocating (and releasing) memory, although this overhead is invisible to programmers. Programs that have created too many objects will be slower (when other conditions are the same) than programs that have created fewer objects with the same functions ).
Furthermore, more closely related to this article is that if you forget to "release" the previously allocated memory, it may cause memory leakage. If the program retains references to objects that will never be used again, these objects will occupy and consume the memory, because the automated Garbage Collector cannot prove that these objects will no longer be used. As we mentioned earlier, if an object is referenced, the object is defined as active and therefore cannot be deleted. To ensure that the memory occupied by the object can be recycled, the programmer must ensure that the object cannot be reached. This is usually done by setting the object field to null or removing the object from the collection. However, note that when a local variable is no longer used, it is not necessary to explicitly set it to null. References to these variables are automatically cleared as the method exits.
In summary, this is the main cause of Memory leakage in the memory hosting language: Object references that are retained but never used again.
Typical Leakage
Now that we know that there is indeed a possibility of Memory leakage in Java, let's look at some typical memory leaks and their causes.
Global set
It is common to have a global data repository in a large application, such as a JNDI tree or a session table. In these cases, you must pay attention to the size of the management repository. There must be a mechanism to remove unnecessary data from the repository.
This can be done in multiple ways, but the most common one is a clear task that runs cyclically. This task verifies the data in the repository and removes any unnecessary data.
Another way to manage the repository is to use reverse link (referrer) to count. The Set collects the number of reverse links for each entry in the set. This requires the reverse link to tell the set when the entry will exit. When the number of reverse links is zero, this element can be removed from the set.
Cache
Cache is a data structure used to quickly find the results of executed operations. Therefore, if an operation is executed slowly, you can cache the operation results and use the cached data when you call the operation next time.
The cache is usually implemented dynamically. The new result is added to the Cache during execution. Typical algorithms are:
Check whether the result is cached. If yes, the result is returned.
If the result is not in the cache, computation is performed.
Add the calculated results to the cache for future calls to this operation.
The problem with this algorithm (or potential memory leakage) lies in the last step. If you call this operation with a considerable number of different inputs, a considerable number of results will be stored in the cache. Obviously, this is not the correct method.
To prevent this potentially destructive design, the program must ensure that there is an upper limit on the memory capacity used by the cache. Therefore, a better algorithm is:
Check whether the result is cached. If yes, the result is returned.
If the result is not in the cache, computation is performed.
If the cache space is too large, the longest result of the cache will be removed.
Add the calculated results to the cache for future calls to this operation.
By removing the result from the cache for the longest time, we actually assume that recently entered data will be more likely to be used than cached data. This is usually a good assumption.
The new algorithm will ensure that the cache capacity is within the predefined memory range. The exact range may be difficult to calculate because the objects in the cache are constantly changing and their references are all-encompassing. Setting the correct size for the cache is a very complex task. You need to balance the memory used with the speed of data retrieval.
Another way to solve this problem is to use the java. lang. ref. SoftReference class to track objects in the cache. This method ensures that these references can be removed, if the VM memory is used up and more heap is needed.
ClassLoader
The use of the Java ClassLoader structure provides many opportunities for Memory leakage. It is precisely because of the complexity of this structure that ClassLoader has so many problems in terms of Memory leakage. The special feature of ClassLoader is that it not only involves "regular" Object references, but also metadata object references, such as fields, methods, and classes. This means that as long as there is a reference to the field, method, class, or ClassLoader object, ClassLoader will reside in JVM. Because ClassLoader can be associated with many classes and their static fields, many memory leaks.
Determine the leak location
The first sign of Memory leakage is: An OutOfMemoryError occurs in the application. This usually happens in the production environment where you least want it to happen, and debugging is almost impossible at this time. It may be because the test environment runs applications in a different way than the production system, resulting in leakage only in production. In this case, some low-overhead tools are required to monitor and find memory leaks. You also need to be able to connect these tools to a running system without restarting the system or modifying the code. Most importantly, you may need to be able to disconnect the tool during analysis to ensure that the system is not disturbed.
Although OutOfMemoryError is usually a memory leak signal, it is also possible that the application is indeed using so much memory; for the latter, or you must increase the number of available JVM heaps, or make some changes to the application so that it uses less memory. However, in many cases, OutOfMemoryError is a memory leak signal. One way to find out is to continuously monitor GC activities and determine whether memory usage increases over time. If so, memory leakage may occur.

Author's "android notes"

Related Article

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.