Java Memory leakage causes and Memory leakage detection tools

Source: Internet
Author: User

Summary
Although Java
Virtual Machine (JVM) and garbage collection
Garbage Collector (GC) is responsible for managing most memory tasks.
Software programs may still appear
Storage leakage. 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 leakage traps for writing Java code.
Trap, and write some best practices that do not 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
Because. 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, it makes life easier for programmers
Memory problems may occur due to mistakes. In short, GC cyclically traces all references from the "root" Object (stack object, static object, object pointed to by the JNI handle, and so on) and
Objects that can be reached are marked 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, assign
(And release) memory will always have overhead, although this overhead is invisible to programmers. Programs that have created too many objects will be slower than those that have created fewer objects after completing the same functions (in
If other conditions are the same ).

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
Retain 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 one
Objects are defined as active, so they 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
Null or an object is removed from the collection. However, note that when a local variable is no longer used, it is not necessary to explicitly set it to null. Introduction to these variables
It is 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 will verify the data in the repository,
And remove any unnecessary data.

Another way to manage the repository is to use reverse link (referrer) to count. The collection is responsible for collecting statistics for each inbound
Number of reverse links at the port. 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 this 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.
Set
The calculated results are added 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
A considerable amount of different input 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
Good algorithms:

Check whether the result is cached. If yes, the result is returned.
If the result is not in the cache, computation is performed.
For example
If the cache space is too large, the result of the longest cache will be removed.
Add the calculated results to the cache for future calls to this operation.
By always removing the slowdown
In fact, we assume that the latest input data is more likely to be used than the longest cached data in the future. 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
They 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 Java. Lang. Ref. softreference class tracking.
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

Java
The use of the 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 field, method, class, or
When classloader is referenced, 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
It occurs in the production environment where you do not want it to happen, and debugging is almost impossible at this time. It may be because the test
The method and
Because the production systems are not identical, leakage only occurs in production. In this case, some low-overhead tools are required to monitor and find memory leaks. You do not need to restart the system or modify the code.
You can connect these tools to a running system. 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 possible that the application is indeed making
Use so much memory; for the latter, you must increase the number of available JVMs or make some changes to the application to make it use less memory. However, in many cases
Outofmemoryerror indicates Memory leakage. One way to find out is to continuously monitor GC activities and determine whether memory usage increases over time. If so, you can
Memory leakage may occur.

Detailed output

There are many ways to monitor spam collector activity. The most widely used is the use of the-xverbose: GC option.
Run the JVM command and observe the output.

[Memory] 10.109-10.235: GC 65536 K-> 16788 K
(65536 K), 126.000 MS
The value (16788 K in this example) after the arrow is the size of the heap used for garbage collection.

Console

It is very boring to view the output of continuous GC detailed statistics. Fortunately, there are tools in this regard. Jrockit
The Management Console displays the graph of the heap usage. With this graph, you can easily see whether the heap usage increases over time.

Figure 1.
Jrockit Management Console

You can even configure this console so that the console can send
Send email. This makes it easier to view memory leaks.

Memory leakage detection tool

There are other dedicated memory leak detection tools. Jrockit Memory Leak
Detector can be used to view memory leaks and further identify the root cause of the leaks. This powerful tool is tightly integrated into jrockit
In JVM, the overhead is very small, and it is easy to access the Virtual Machine heap.

Advantages of professional tools

Once you know that a memory leak occurs, you need more professional tools to find out why the leak occurs. JVM won't tell itself
Your. These professional tools obtain information about the memory system from the JVM in two ways: jvmti and byte code
Instrumentation ). Java Virtual Machine Tools
Interface (jvmti) and its predecessor Java Virtual Machine profiling (Java Virtual Machine profiling)
Interface (jvmpi) is a standardized interface for external tools to communicate with JVM and collect information from JVM. Bytecode technology refers to the technology that uses detectors to process bytecode to obtain information required by tools.
.

These two technologies have two disadvantages for memory leak detection, which makes them unsuitable for production environments. First, they are stored in the memory
The overhead of occupation and performance reduction cannot be ignored. Information about heap usage must be exported from JVM in some way and collected to tools for processing. This means to allocate memory for the tool. Information export also affects
The performance of JVM is affected. For example, the garbage collector runs slowly when collecting information. Another disadvantage is that you must always connect the tool to the JVM. This is not possible: connect the tool to a started
On the JVM, perform analysis, disconnect the tool, and keep the JVM running.

Because jrockit Memory Leak
Detector is integrated into JVM, so there are no such two shortcomings. First, many processing and analysis tasks are performed within the JVM, so there is no need to convert or recreate any data. Processing also
Piggyback can be carried on the garbage collector itself, which means the speed is improved. Second, as long as the JVM is using the-xmanagement option (remote
JMX interface monitoring and managing JVM) started, Memory Leak
Detector can be connected to or disconnected from the running JVM. When the tool is disconnected, nothing is left in the JVM, And the JVM will run the code at full speed, just as before the tool is connected
Sample.

Trend Analysis

Let's take a deeper look at the tool and how it is used to track memory leaks. The first step is
You need to find out what data is leaked-Which class object causes the leakage? Jrockit Memory Leak
Detector calculates the number of existing objects in each class during each garbage collection. If the number of objects in a specific class increases over time ("growth rate"), memory may occur.
Leakage.


Figure 2. Memory
Leak Detector trend analysis View

Because the leakage may be as small as a small stream, trend analysis must run for a long time. In a short period of time, some
Class, and then they will fall. However, the overhead of trend analysis is very small (the biggest overhead is to send data packets from jrockit to memory leak every time garbage collection is performed.
Detector ). Overhead should not be a problem with any system-even a system running at full speed in production.

At first, the number will jump continuously, but after a period of time they will stabilize and show which classes are growing.

Find the root cause

Sometimes it is enough to know which class objects are being leaked to illustrate the problem. These classes may only be used for a very limited part of the code.
The Code performs a quick check to show the problem. Unfortunately, it is very likely that only such information is insufficient. For example, objects in the Java. Lang. string class are often leaked.
But because the string is used in the whole program, this is not very helpful.

What we want to know is what other objects are associated with the leaked objects? In this example, it is a string. Why are the leaked objects still
Exist? Which objects retain references to these objects? However, all objects that can be listed that are retained for string reference will be so many that they are of no practical use. To limit the number of data, you can
Group data by class to see which other object classes are associated with the leaked object (string. For example, string is common in hashtable, so we may see
To the hashtable data item object associated with the string. We can find the hashtable object related to the hashtable data items and
String (3 ).


Figure 3.
Sample view of the type chart seen in the tool

Reverse push

Because we still view objects with class objects instead of individual objects, we do not know which hashtable is used.
Leakage. If we can figure out how big all hashtable is in the system, we can assume that the biggest hashtable is the one that is being leaked (because as time passes
It will accumulate leaks and increase significantly ). Therefore, a list of all hashtable objects and the amount of data they reference will help us identify the exact cause of leakage.
Hashtabl.


Figure 4.
Interface: hashtable objects and the list of the number of referenced data

The computing overhead of the number of data referenced by an object is very large (you need to use this object as the root traversal reference graph ).
It will take a lot of time. If you understand the internal implementation principle of hashtable, you can find a shortcut. The hashtable contains the number of hashtable data items.
Group. This array increases with the number of objects in hashtable. Therefore, to find the maximum hashtable, we only need to find the maximum number of data items that reference hashtable.
Group. This is much faster.


Figure 5.
Interface: Maximum hashtable data item array and its size list

Further steps

When a leaked hashtable instance is found, we can see which instances are referencing this
Hashtable, and push it back to see which hashtable is leaking.


Figure 6.
This is the instance diagram in the tool.

For example, the hashtable may be named by an object of the myserver type
In the activesessions field. This information is usually enough to find the source code to locate the problem.


Figure 7.
Check the object and its reference to other objects

Locate the allocation location

It is useful to check where objects are allocated when tracking memory leaks. Only know how they are associated with other objects (that is, what
Objects Reference them) is not enough, and information about where they are created is also useful. Of course, you do not want to create auxiliary components of an application to print the stack trace (Stack
Trace ). You do not want to connect an analytic program to the production environment when running the application just to track memory leaks.

With jrockit Memory Leak
Detector. The code in the application can be dynamically added during allocation to create a stack trace. These stack traces can be accumulated and analyzed in tools. This function is not available if it is not enabled.
Production cost, which means that allocation and tracking can be performed at any time. Jrockit
The compiler dynamically inserts code to monitor the allocation, but only for the requested specific class. Even better, all the added code is removed during data analysis, and nothing left in the code will cause application performance degradation.
Low.


Figure 8.
Stack trace allocated by string during execution of the sample program

Conclusion

Memory leakage is hard to detect. This article focuses on several best practices to avoid Memory leakage, including always remember in the data structure.
Content, and closely monitor memory usage to discover sudden increases.

We have all seen jrockit Memory Leak
How detector is used in production systems to track memory leaks. The tool uses a three-step method to identify leaks. First, analyze the trend to find out which class objects are being leaked. Next
To see which other classes are associated with the leaked class objects. Finally, we will further study individual objects to see how they are correlated. Dynamic stack and
Trace. These features and the features that the tool tightly integrates into JVM allow you to use a secure
Powerful way to track Memory leakage
Vulnerability and repair.

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.