Java Memory leak analysis and solution

Source: Internet
Author: User
Tags stack trace

Java memory leaks are the problems that every Java programmer will encounter, the program is running all the normal local, but the deployment of the remote memory will be unlimited growth, the final system is paralyzed, then how the fastest best detection program stability, to prevent system crashes, The author uses his own personal experience to share with the netizens how to solve these problems.

Java is now very popular as one of the most popular programming languages on the Internet. Our web applications are primarily developed in the Java language and are broadly divided into three levels of clients, servers, and databases. During the testing process, we found that a program module system memory and CPU resource consumption increased sharply, and continued to grow until java.lang.OutOfMemoryError occurred. The analysis of Java memory leaks is a major factor in destroying the system. Here we share with you the process of detecting and processing Java memory leaks that we have encountered during the development process.

  First, how to manage the memory in Java

To determine if there is a memory leak in Java, we must first understand how Java manages memory. The memory management of Java is the allocation and release of objects. In Java, the allocation of memory is done by the program, and the release of memory is done by the garbage collector (garbage COLLECTION,GC), the programmer does not need to call the function to free memory, but it can only reclaim the useless and no longer referenced by other objects of the space occupied by those objects.

The memory garbage collection mechanism of Java is to check the reference chain from the main running object of the program, and when it is traversed, it is found that there are no referenced orphaned objects as garbage collection. In order to properly dispose of objects, the GC must monitor the running state of each object, including the application, reference, reference, assignment, etc. of the object, which the GC needs to monitor. The object's state is monitored to release the object more accurately and in a timely manner, and the fundamental principle of releasing the object is that the object is no longer referenced.

In Java, these useless objects are collected by the GC, so programmers do not need to consider this part of the memory leak. Although we have several functions that can access the GC, such as the function System.GC () that runs the GC, the function does not guarantee that the JVM's garbage collector will execute, as defined by the Java language Specification. Because different JVM implementations may use different algorithms to manage the GC. Typically, GC threads have a lower priority level. There are a number of policies that the JVM calls the GC, some of which are used to a certain extent, the GC starts to work, there are timed executions, there is a gentle execution of the GC, and some interrupt-execution GC. But generally speaking, we don't need to care about this.

  Ii. What is a memory leak in Java

The main reason for a memory leak is that you previously requested a memory space and forgot to release it. If a reference to a useless object exists in the program, those objects will reside in memory and consume memory because the garbage collector GC cannot be verified that the objects are no longer needed. If there is a reference to the object, the object is defined as a "valid activity" and is not freed. To make sure that the object's memory will be recycled, we must make sure that the object is no longer in use. The typical practice is to set the object data member to null or to remove the object from the collection. However, when a local variable is not required, it is not required to be significantly null, because when a method executes, these references are automatically cleaned up.

In Java, the memory leak is the existence of some assigned objects, these objects have the following two characteristics, first of all, these objects are referenced, that is, in a tree diagram, there is a branch path can be connected with, second, these objects are useless, that is, the program will no longer use these objects. If the object satisfies both conditions, these objects can be judged as a memory leak in Java, which is not reclaimed by the GC, but it consumes memory.

Here is a frequently seen example, in the following code, the loop applies to the Object object, and put the requested objects into a vector, if only the object itself, but because the vector still refers to the object, so this object is not recyclable GC. Therefore, if the object has to be removed from the vector after it has been added to the vector, the simplest way is to set the vector object to null.

Vector v = new vector, for (int i = 1; i <; i++) ... {Object o = new Object (); V.add (o); o = null;} At this point, all object objects are not freed because the variable v refers to these objects.

In fact, these objects are already useless, but also referenced, the GC is powerless (in fact, the GC thinks it is useful), which is the most important cause of memory leaks. Then cite another example to illustrate the memory leaks in Java. Suppose there is a log class logger, which provides a static log (String msg), and any other class can call LOGGER.LOG (message) to record the contents of the message into the system's log file.

The logger class has a static variable of type HashMap temp, and each time the log (message) is executed, the value of the message is first written to temp (with the current thread + current time as the key). Delete the entries in temp from the current thread and the current time key before exiting. Note that the current time here is constantly changing, so log execution deletes entries before exiting, and cannot delete entries that were written at the beginning of the execution. Thus, any string passed as a parameter to log will eventually be referenced by the logger static variable temp and cannot be recycled, and this object remains what we call a Java memory leak. In general, memory leaks in memory management are the main reason: object references that remain but are never used again.

Three, several typical memory leaks

We know there is a memory leak in Java, so let's take a look at a few typical leaks and find out why and how they're going to work.

3.1 Global Collections

It is common to have a wide variety of global data warehouses in large applications, such as a jndi-tree or a session table. In these cases, you must be aware of the size of the management repository. There must be some mechanism to remove data that is no longer needed from the repository.

There are often many different forms of resolution, the most common of which is a cycle-run cleanup job. This job verifies the data in the warehouse and clears all the data that is not needed.

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

3.2 Cache

Caches a data structure that is used to quickly find the results of an operation that has been performed. Therefore, if an operation executes a resource that requires more resources and is used more than once, it is common practice to cache the results of the operations of the commonly used input data in order to use the cached data the next time the operation is invoked. Caches are usually implemented dynamically, and if the cache settings are incorrect and the cache is heavily used, the result is a memory overflow, so you need to balance the amount of memory used with the speed at which data is retrieved.

A common solution is to use the Java.lang.ref.SoftReference class to persist objects into the cache. This method ensures that when a virtual machine runs out of memory or needs more heaps, it can release references to those objects.

Class 3.3 Loaders

The use of the Java class Loader provides a lot of opportunity for memory leaks. The class loader generally has a complex structure, because the class loader is not just about "general" object references, but also about references inside objects. such as data variables, methods, and various classes. This means that as long as there is a class loader for data variables, methods, classes, and objects, the class loader will reside in the JVM. Since class loaders can be associated with many classes and can also be associated with static data variables, a significant amount of memory can leak.

  Iv. how to detect and handle memory leaks

How to find the cause of a memory leak generally there are two steps: The first is to arrange for experienced programmers to walk through and analyze the code to find out where the memory leak occurred, and the second is to use a dedicated memory leak test tool to test.

The first step in the work of code walk, you can arrange for the system business and development language tools familiar to the developer of the application of the code to cross-check, try to find out the code in the database connection declaration and result set is not closed, code redundancy and other failure codes.

The second step is to detect a Java memory leak. Here we usually use some tools to check the memory leak of Java programs. There are several professional tools on the market to check the Java memory leaks, they basically work the same principle, all through the monitoring of the Java program runtime, all object application, release and other actions, the memory management of all the information to statistical, analysis, visualization. The developer will use this information to determine if the program has a memory leak problem. These tools include Optimizeit Profiler,jprobe profiler,jinsight, Rational company Purify, etc.

4.1 Detecting the presence of a memory leak

Here we will briefly describe the process in which we use the Optimizeit check. Usually, after knowing that a memory leak occurs, the first step is to figure out what data was leaking and which class of objects caused the leak.

Generally speaking, a normal system after its stable operation of its memory consumption is basically stable, should not be unrestricted growth. Similarly, there is a relatively stable upper limit on the number of objects used for any one class, and should not be continuously growing. Based on this basic assumption, we continuously observe the size of the memory used by the system and the number of instances, and if the size of the memory continues to grow, there is a memory leak in the system, if the number of instance objects for a particular class grows over time (that is, the so-called "growth rate"). Indicates that an instance of this class might have a leak condition.

On the other hand, the first sign of a memory leak usually occurs is outofmemoryerror in the application. In this case, you need to use some of the less expensive tools to monitor and find memory leaks. While it is possible that the application is actually using so much memory, OutOfMemoryError can 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 are signals of memory leaks. One way to find out is to continuously monitor GC activity to determine if memory usage increases over time. If this is the case, a memory leak may occur.

4.2 Ways to handle memory leaks

Once you know that a memory leak does occur, you need a more professional tool to find out why the leak occurred. The JVM is not going to tell you. There are basically two ways these professional tools get memory system information from the JVM: JVMTI and Bytecode Technology (byte code instrumentation). Java Virtual Machine Tool interface (Java VM Tools INTERFACE,JVMTI) and its predecessor Java hypervisor interface (Java virtual machines Profiling Interface, JVMPI) is a standardized interface for external tools to communicate with the JVM and collect information from the JVM. Bytecode technology refers to the technique of using a probe to process bytecode to obtain the information needed by the tool.

Optimizeit is a product of Borland, which is primarily used to assist in code optimization and fault diagnosis of software systems, where the Optimizeit Profiler is primarily used for memory leak analysis. The heap view of profiler is used to observe the size of memory used by the system and the number of instances allocated for each class.

First, the profiler will perform a trend analysis to find out which class of objects are leaking. Four memory snapshots can be obtained after the system has been running for a long time. A comprehensive analysis of these four memory snapshots, if the memory usage of each snapshot is higher than the last time, it can be assumed that the system has a memory leak, to find out in four snapshots of the number of instances to maintain the growth of classes, these classes can be initially identified as a leak. Through data collection and preliminary analysis, it can be concluded that there is a memory leak in the system and which objects are leaking (leaked).

Next, look at what other classes are associated with the objects of the leaking class. The memory leaks in Java have been mentioned as useless object-keeping, simply because the coding error resulted in the existence of a reference chain that should not have existed (which caused the referenced object to be unable to be freed), so the task of memory leak analysis was to find out the redundant reference chain and find out the reason for its formation. It is useful to see where objects are assigned. It is not enough to know just how they are associated with other objects (that is, which objects reference them), and it is also useful for information about where they are created.

Finally, explore the individual objects to see how they relate to each other. With the profiler tool, code in your application can be dynamically added at allocation time to create a stack trace. There is also a dynamic stack trace that can be assigned to all objects in the system. These stack traces can be accumulated and analyzed in the tool. For each leaked instance object, there must be a chain of references from a traction object that arrives at the object. The traction object in the stack space loses its traction after being ejected from the stack and becomes a non-traction object. Therefore, after a long run, the object being leaked is basically drawn by the traction object as the static variable of the class.

In a word, although Java has the function of automatically reclaiming and managing memory, memory leaks are not negligible, it is often an important factor that destroys the stability of the system.

Article Address: http://blog.chinaunix.net/uid-11313293-id-2883375.html

Java Memory leak analysis and solution

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.