JAVA garbage collection mechanism and memory leak __java

Source: Internet
Author: User
Tags garbage collection memory usage throwable stringbuffer

1. Core idea of garbage collection algorithm

The Java language establishes a garbage collection mechanism for tracking objects that are in use and for discovering and reclaiming objects that are no longer in use (references). This mechanism can effectively guard against the two risks that may occur in dynamic memory allocation: the memory exhaustion caused by excessive memory garbage, and an illegal memory reference caused by improper memory release.

The core idea of the garbage collection algorithm is: The virtual machine available memory space, that is, the object in the heap space to identify, if the object is being referenced, then call it the living object, conversely, if the object is no longer referenced, then the garbage object, you can reclaim its occupied space for redistribution. The selection of garbage collection algorithm and the reasonable adjustment of the parameters of garbage collection system directly affect the performance of the system, so it is necessary for the developers to have a more in-depth understanding.

2. Conditions that trigger the primary GC (garbage Collector)

The JVM has a high frequency of GC, but because the GC takes a very short time, it has little impact on the system. What is more noteworthy is the trigger condition of the primary GC, because it has an obvious effect on the system. In general, there are two conditions that trigger the primary GC:

① GC is invoked when the application is idle, that is, no application thread is running. Because the GC is in the lowest-priority thread, the GC thread is not invoked when the application is busy, except for the following conditions.

The GC is invoked when the ②java heap is low on memory. When the application thread is running and a new object is created during the run, if there is not enough memory space, the JVM is forced to call the GC thread to reclaim the memory for the new assignment. If the GC is not able to meet the requirements of memory allocation after the first time, the JVM will do two more GC for further attempt, if still unable to meet the requirements, the JVM will report "Out of Memory" error, the Java application will stop.

Because the main GC is determined by the JVM based on the system environment, and the system environment is constantly changing, the main GC runs with uncertainty and cannot predict when it will inevitably occur, but 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, the operation of the program will directly affect the system environment changes, thus affecting the GC trigger. If you do not design and encode the characteristics of GC, there will be a series of negative effects such as memory presence. To avoid these effects, the basic principle is to minimize garbage and reduce the cost of the GC process as much as possible. Specific measures include the following:

(1) do not explicitly invoke System.GC ()

This function recommends that the JVM be the primary GC, although it is recommended rather than certain, but in many cases it triggers the primary GC, which increases the frequency of the primary GC, and increases the number of intermittent pauses.

(2) Minimize the use of temporary objects

The temporary object becomes garbage after the function call is dropped, and the less temporary variable is the equivalent of reducing garbage generation, thus prolonging the occurrence of the second triggering condition mentioned above and reducing the chance of the primary GC.

(3) It is best to explicitly null an object when it is not in use

In general, NULL objects are treated as garbage, so it is more efficient for GC collectors to determine garbage by explicitly setting unused objects to null.

(4) try to use StringBuffer instead of string to accumulate strings (see blog Another article Java string and StringBuffer)

Because string is a fixed-length string object, accumulating a string object is not amplified in a string object, but rather creates a new string object, such as STR5=STR1+STR2+STR3+STR4, that produces multiple garbage objects during execution. Because a new string object must be created for the secondary "+" operation, these transition objects are meaningless to the system and will only add more garbage. To avoid this situation, you can use StringBuffer to accumulate strings, because the StringBuffer is variable length, it expands on the original basis, does not produce intermediate objects.

(5) can use basic type such as Int,long, do not use Integer,long object

The base type variable consumes much less memory resources than the corresponding object, and if it is not necessary, it is best to use the base variable.

(6) use static object variables as little as possible

Static variables are global variables and are not reclaimed by GC, and they can occupy memory all the time.

(7) the time that the scatter object was created or deleted

Focusing on a large number of new objects in a short time, especially large objects, can result in a sudden need for large amounts of memory, which, in the case of the JVM, can only be primary GC to reclaim memory or consolidate memory fragmentation, thereby increasing the frequency of the primary GC. The same is true for deleting objects centrally. It causes a sudden emergence of a large number of garbage objects, the inevitable reduction of free space, thereby greatly increasing the next time to create a new object to force the main GC opportunity.

4. GC and Finalize methods

⑴gc Method Request Garbage collection

Using System.GC () can request Java garbage collection regardless of which garbage collection algorithm the JVM uses. It should be noted that calling System.GC () is only a request. When the JVM accepts this message, it does not do garbage collection immediately, but simply weights several garbage collection algorithms that make garbage collection operations easy to occur, occur earlier, or recycle more.

⑵finalize method to pivot garbage collector's operation

Before the JVM garbage collector collects an object, it is generally required that the program call the appropriate method to free the resource, but in the absence of a clear release of resources, Java provides a default mechanism to terminate the object's release of resources, which is finalize (). Its prototype is:

protected void Finalize () throws Throwable

After the Finalize () method returns, the object disappears and the garbage collection starts executing. The throws Throwable in the prototype indicates that it can throw any type of exception.

As a result, when objects are about to be destroyed, some remedial work is sometimes needed. You can write these actions in the Finalize () method.

protected void Finalize ()

{

Finalization code here

}

⑶ code Example

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 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 garbage collector

}

}

5. Java memory leaks

Because of the garbage collection mechanism, any unreachable objects (objects that are no longer referenced) can be reclaimed by garbage collector threads. So the usual Java memory leaks refer to unconscious, unintentional object references, or unconscious object retention. An unconscious object reference is one in which the developer of the code has already used the object, but accidentally saves a reference to the object because of a coded error (the existence of the reference is not the subjective will of the coder), which keeps the object from being recycled by the garbage collector. This space, which would have been thought to have been released, could be considered "leaked".

Consider the following program, in the Objstack class, using the push and pop methods to manage objects in the stack. Indexes (index) in two methods are used to indicate the next available location in the stack. The push method stores a reference to the new object and increases the index value, while the Pop method decreases the index value and returns the topmost 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 an object to it, at which point the value of index is 64, then the Pop method is called 32 times, then the value of index becomes 32, and the stack means that the space in the stack should be collected In fact, the pop method only reduces the index value, and the stack still keeps a reference to those objects. Therefore, 32 useless objects will not be collected 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 (),//new a Objstack object, and invokes the parameter constructor. The allocated stack obj array has a space size of 64 and can save 64 objects, starting at 0.
while (I < 64)
{
Tempobj = new Object ()//loop new obj object, storing object one by one of each loop in the stack obj array.
Stack1.push (Tempobj);
i++;
System.out.println ("First" + i + "secondary stack" + "t");
}
while (i > 32)
{
Tempobj = Stack1.pop ();//This creates a waste of space.
The correct pop method can be changed to indicate that when a reference is returned, the stack deletes references to them, so the garbage collector can recycle them later.

i--;
System.out.println ("First" + (64-i) + "secondary out stack" + "/t");
}
}

}


How to eliminate memory leaks

Although the Java Virtual Machine (JVM) and its garbage collector (garbage COLLECTOR,GC) are responsible for managing most of the memory tasks, a memory leak may still occur in the Java software program. In fact, this is a common problem in large projects. The first step in avoiding a memory leak is to figure out how it happened. This article describes some of the common memory leak traps for writing Java code, as well as some best practices for writing code that does not leak. Once a memory leak occurs, it is very difficult to point out the code that caused the leak. This article also introduces a new tool to diagnose leaks and to identify root causes. The cost of the tool is so small that it can be used to look for a memory leak in a system that is in production.

The role of the garbage collector

While the garbage collector handles most memory management issues, making life easier for programmers, programmers can still make mistakes that lead to memory problems. Simply put, the GC loops through all references from the root object (the Stack object, static object, object that the JNI handle points to, and so on) and marks all objects that it can reach as active. The program can manipulate only these objects, and other objects are deleted. Because a GC makes it impossible for a program to reach an object that has been deleted, it is safe to do so.

While memory management can be said to be automated, this does not prevent programmers from thinking about memory management issues. For example, allocating (and freeing) memory always has overhead, although this overhead is not visible to programmers. Programs that create too many objects will be slower (and other conditions are the same) than those that create fewer objects than the same functionality.

Moreover, more closely related to this article is that if you forget to "free" previously allocated memory, you may cause a memory leak. If your program retains references to objects that will never be used, these objects will consume and run out of memory because the automated garbage collector cannot prove that these objects will no longer be used. As we said earlier, if there is a reference to an object, the object is defined as active and cannot be deleted. To ensure that the memory used by the object is recycled, the programmer must ensure that the object does not arrive. This is usually done by setting the object field to null or removing the object from the collection (collection). However, note that it is not necessary to explicitly set the local variable to NULL when it is no longer in use. References to these variables are automatically cleared as the method exits.

In a nutshell, this is the main reason for memory leaks in a memory managed Language: Object references that are preserved but never used again.

Typical leaks

Now that we know that there is a real possibility of memory leaks in Java, let's look at some typical memory leaks and their causes.

Global Collection

It is common to have a global repository of data in large applications, such as a jndi tree or a session table. In these cases, care must be taken to manage the size of the repository. There must be some mechanism to remove data that is no longer needed from the repository.

This can be done in a number of ways, but the most common one is some sort of cleanup task that runs periodically. The task verifies the data in the repository and removes any data that is no longer needed.

Another way to manage a repository is to use a reverse link (referrer) count. The collection is then responsible for counting the number of backlinks for each entry in the collection. This requires that the reverse link tell the collection when it will exit the portal. When the number of reverse links is zero, the element can be removed from the collection.

Cache

Caching is a data structure that is used to quickly find the results of an action that has been performed. Therefore, if an operation is slow to execute, for commonly used input data, the result of the operation can be cached and the cached data will be used the next time the operation is called.

Caching is typically implemented dynamically, with new results added to the cache at execution time. The typical algorithms are:

Checks whether the result is in the cache and, if so, returns the result.
If the result is not in the cache, the calculation is done.
Adds the computed results to the cache so that subsequent calls to the operation can be used.
The algorithm's problem (or latent memory leak) is out in the final step. If there are quite a few different inputs when the operation is invoked, a considerable number of results are stored in the cache. Obviously it's not the right approach.

To prevent this potentially damaging design, the program must ensure that there is an upper limit on the amount of memory used for caching. Therefore, a better algorithm is:

Checks whether the result is in the cache and, if so, returns the result.
If the result is not in the cache, the calculation is done.
If the cache occupies too much space, remove the longest cache result.
Adds the computed results to the cache so that subsequent calls to the operation can be used.
By always removing the longest cache result, we actually make the assumption that in the future, the most recently entered data is more likely to be used than the longest cached data. This is usually a good assumption.

The new algorithm will ensure that the cached capacity is within the predefined memory range. The exact range can be difficult to calculate because the objects in the cache are changing and their references are all-encompassing. Setting the correct size for the cache is a very complex task, and you need to balance the amount of memory used and the speed with which the data is retrieved.

Another way to solve this problem is to use the Java.lang.ref.SoftReference class to track objects in the cache. This approach ensures that these references can be removed if the virtual machine is running out of memory and needs more heap.

ClassLoader

The use of the Java ClassLoader architecture provides a lot of opportunity for memory leaks. It is the complexity of the structure itself that causes ClassLoader to have so many problems with memory leaks. The special thing about ClassLoader is that it involves not only "general" object references, but also meta object references, such as fields, methods, and classes. This means that whenever there is a reference to a field, method, class, or ClassLoader object, ClassLoader resides in the JVM. Because the ClassLoader itself can associate many classes and their static fields, there is a lot of memory being leaked.

Determine the location of the leak

The first sign of a memory leak is that there is a outofmemoryerror in the application. This usually happens in the production environment that you least want it to happen, and debugging is almost impossible at this point. It is possible that the test environment runs the application in a way that is not exactly the same as the production system, causing the leak to occur only in production. In this case, you need to use some of the less expensive tools 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. Perhaps most importantly, when profiling, you need to be able to disconnect the tool and keep the system undisturbed.

While OutOfMemoryError is usually a signal of a memory leak, it is possible that the application is actually using so much memory, or that the latter must either increase the number of heaps available to the JVM or make some changes to the application so that it uses less memory. However, in many cases, outofmemoryerror is a signal of memory leaks. One way to find out is to continuously monitor the activities of the GC to determine whether memory usage has increased over time. If this is the case, a memory leak may occur.

A lot of people are talking about the memory leak problem, of course, for C + +, this should be the age-old problem, but very many Java personnel also more and more to discuss this issue, I write a summary here, I hope to have a certain reference value.

Memory leak of the concept

1.c/c++ is the programmer's own memory management, and Java memory is automatically recycled by GC.

Although I am not very familiar with C + +, but this should not make common sense mistakes.

2. What is a memory leak?

Memory leaks are memory that cannot be reclaimed in the system, sometimes resulting in out-of-memory or system crashes.

A memory leak is a condition in which memory is not released in C + +.

3.Java There is a memory leak

We have to admit this before we can discuss it. Although there is a memory leak in Java, there is basically no need to be very concerned about him, especially those who are not fastidious about the code itself.

Memory leaks in Java are, of course, objects that are useless but cannot be reclaimed by the garbage collector. And even if there is a memory leak problem exists, it will not necessarily show.

The parameters in the 4.Java are all passed values.

There is basically no objection to the basic type, but we cannot disagree with the reference type.

Java memory leaks

The JVM recovery algorithm is very complex and I don't know how they do it, but I only know what they're going to do: it's recyclable for objects that are not referenced. So you're going to make a memory leak.:<

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.