Preliminary probe Java's memory management
SUMMARY: This article discusses how to perform memory management in the Java programming method. Memory management mainly involves the creation of objects and the recycling of objects, and its recycling is mainly completed by Java's garbage collector. However, although there are garbage collection mechanisms to help programmers have completed a lot of work, there is still a certain amount of memory leaks, and long-term accumulation will cause the system to face the danger of collapse. In the development process, we need to pay attention to how questions to optimize your code.
Java's memory management includes two important tasks: memory allocation and memory recycling. In memory allocation, the goal is to reduce the object you need to create. Memory recycling is a universal reason for performance degradation. In other words, the more objects in memory, the more difficult garbage collection is.
In J2EE applications, the two most common memory related issues are: free objects (also known as memory leaks) and object cycles (refer to a large number of frequent creation and deletion - reflecting in Java to release reference objects).
For memory creation, we need a conservative attitude. If there is any Java code allocated to allocate a large number of temporary objects (or some of the objects of multiple phagrates), and when these objects are no longer needed, they are not unable to cancel the limit of memory.
But is Java also have a problem with memory leakage? Most Java programmers know that a biggest benefit of Java relative to C language is that they don't have to worry about the distribution and recycling of memory. As long as you create an object, when the application no longer needs these objects, the Java will delete these objects, reclaim objects through a mechanism that is "garbage collection" when the object is not needed, or after its life cycle. The memory occupied. This handling has already solved other programming languages, such as annoying problems existing in C language - memory leakage. So what is the truth?
First, how Java manages memory
Let's first meet, how Java manages memory.
As we said, Java's memory management is the allocation and recycling of objects. In Java, in addition to the basic type, programmers need to apply for memory spaces for each object via the new keyword, all objects allocate space in the heap (HEAP). In addition, the recovery of the object is determined and executed by the GC. Memory allocation is done by programmers, while recycling is completed by GC, this way is really a good simplified programmer, but also adds JVM's work. This is also one of the reasons why Java program is slow. Because GC is to properly release the object, it must monitor the operational status of each object, including the application, reference, reference, assignment, etc., GC needs to monitor. This will be more accurate, timely recycling objects, the root principle of its recycling is that the object is no longer referenced.
In order to better understand the working principle of GC, we can consider the object to be a vertex of the map, accounting the reference relationship as a view of the map, and pointing from the reference to the subject. Alternatively, each thread object can be used as a starting top point of a graph, such as most programs start from the MAIN process, then the figure is a root tree starting at the top of the MAIN process. In this figure, the root top can be a valid object, and the GC will not reclaim these objects. If an object (connecting sub-map) is unreachable with this root point (note that the picture is a map), then we think this (these) objects are no longer referenced, which can be recycled by GC.
Hereinafter, we will give an example to indicate how to use a map to represent memory management. For every moment of the program, we have a memory allocation of the JVM to represent the JVM. The following picture is a schematic diagram of the left program runs to Chain 6.
Java uses a way to perform memory management in a way that can eliminate the problem of reference loops, such as three objects, citing each other, as long as they are not arrogant, the GC can also recover them. The advantage of this approach is that the management of memory is high, but the efficiency is low. Another commonly used memory management technology is a counter, such as a COM model, a counter mode management component, which is a low precision line (it is difficult to handle cyclic references) compared to the map, but the execution efficiency is high. Java2 enhances the memory management function, adds a java.lang.ref package, which defines three reference classes. These three reference classes are SoftReference, WeakReference, and PhantomReference. By using these reference classes, programmers can interact with GC to a certain extent to improve the working efficiency of GC. These reference classes are intensity between the reachable objects and the irreparable objects. The intensity of their reference is as follows:
Creating a reference object is also very easy, for example, if you need to create a Soft Reference object, first create an object and use a normal reference method (can be object); then create a SoftReference reference to this object; finally set a normal reference to NULL. In this way, this object has only one Soft Reference reference. At the same time, we call this object for the Soft Reference object.
The main features of Soft Reference are strongly referenced. This type of memory is only recycled when memory is not enough, so they are usually not recycled when memory is sufficient. In addition, these reference objects can also be set to NULL before Java throws OutofMemory exceptions. It can be used to implement a cache of some common pictures, implement the function of cache, to ensure maximum use of memory but does not cause OutofMemory. The use of pseudo code for this type of reference is given below:
// Apply for an image object
Image image = new image (); // Create an image object
...
// Using Image
...
// Use the image to set it to the Soft reference type, and release strong references;
SoftReference Sr = New SoftReference (Image);
Image = null;
...
// Next time
IF (SR! = null) image = sr.get ();
Else {
// Due to the low memory, it is released, so it is necessary to reload;
Image = new image ();
SR = New SoftReference (image);
}
The maximum difference between the Weak reference object and the Soft reference object is that when the GC is recycled, it is necessary to check whether the Soft reference object is reclaimed by the algorithm, and the GC is always recycled for the WEAK reference object. The Weak reference object is easier and is recycled by GC faster. Although the GC will renew WEAK objects at runtime, complex relations of Weak objects often require several GC operations to complete. WEAK reference objects are often used in the MAP structure, references objects with large amount of data, once the object's strong reference is NULL, GC can quickly recover the object space.
The use of PHANTOM is small, mainly used to assist the use of the Finalize function. PHANTOM object refers to some objects, which are completed in the Finalize function, and is irreparable objects, but they have not been recycled by GC. This object can assist Finalize for some later recycling work, and we enhance the flexibility of resource recycling mechanisms by covering Reference's CLEAR () method. Second, what is the memory leak in Java
Below, we can describe what is memory leak. In Java, memory leaks exist some assigned objects, which have the following two features. First, these objects are up, that is, in the figure, there is a path to be connected thereto; secondly, these objects are useless These objects will not be used after the program will be used later. If the object satisfies these two conditions, these objects can be determined as memory leaks in Java, which will not be recovered by GC, but it takes up memory.
In C , the range of memory leaks is larger. Some objects are assigned a memory space, and then they are not arrogant. Due to the GC in C , these memory will never receive it. In Java, these irreparable objects are responsible for recycling by GC, so the programmer does not need to consider this part of the memory leak.
Through analysis, we know that for C , programmers need to manage their side and vertices themselves, and for Java programmers only need to manage edges (do not need to manage vertices release). In this way, Java improves the efficiency of programming.
Therefore, through the above analysis, we know that there is also memory leak in Java, but the range is smaller than C . Because Java guarantees from language, any object is up to, and all non-objects are managed by GC.
For programmers, GC is basically transparent and invisible. Although we only have several functions to access GC, such as running GC's function system.gc (), but according to Java language specification definition, the function does not guarantee the JVM garbage collector will be executed. Because, different JVM implementations may use different algorithms to manage GC. Typically, the priority of the GC thread is lower. There are many kinds of JVM calling GC, and some are when memory uses to a certain extent, GC starts working, and there is a timed execution, some are gentle execution GC, and some are interrupt implementation GC. But in general, we don't need to care about it. Unless otherwise on some specific occasions, GC performs the performance of the application, such as web-based real-time systems, such as online games, etc., users do not want GC to suddenly interrupt the application execution and garbage recycling, then we need to adjust GC parameters Allow GC to release memory through a gentle manner, for example, decompose garbage recovery into a series of small steps, and the HotSpot JVM provided by Sun supports this feature.
In summary, for GC, it will be statistically useless when an object is no longer referenced. This concept is illustrated below.
The above explains two classes with different life cycles in the Java application execution interval. Class A is first instantiated and will exist within a long period of time or the entire life cycle of the program. At some point, class B is created, class A adds a reference to this newly created class. When B is created and is contacted, if the reference to the B class is not eliminated in A, even if the class B is no longer needed, the class B will still exist even after the next garbage collection period is executed, and the memory space is occupied. .
Third, when will you pay attention to memory leak?
If your program issues a Java.lang.OutofMemoryError error after execution, the memory leak is definitely a major suspect. In addition to this obvious case, when should you pay attention to memory leakage? The programmer who holds the perfectist view will definitely answer, and you should find and correct all memory vulnerabilities. However, there are several aspects that need to be considered before drawing this conclusion, including the surplus and vulnerabilities of the program. There is a possibility that the garbage collector may never run within the survival of the application. This is the case if the JVM does and whether it will call the garbage collector - even if the program explicitly calls System.gc (). Typically, the JVM does not automatically run the garbage collector when the current available memory satisfies the memory requirements of the program. When the available memory does not meet the requirements, the JVM will first try to release more available memory by calling garbage collection. If this attempt still does not release enough resources, JVM will get more memory from the operating system until the maximum limit allowed.
For example, consider a small Java application that displays some simple user interface elements for modifying the configuration, and it has a memory leak. It is likely that the garbage collector will not be called when the application is shut down, as JVM is likely to have enough memory to create all the objects required for the program, and there will be no remaining in memory. Therefore, in this case, even if some "dead" objects occupy memory during program execution, it doesn't actually use it.
If the Java code being developed is running on the server 24 hours a day, the impact of memory leaks here is much larger than the impact in our configuration utility. In some of the codes for a long time, even minimal leaks can cause the JVM to exhaust all available memory.
In contrast, even if the program is shorter, if there is any Java code allocated to allocate a large number of temporary objects (or some objects of multiple phagocytical memory), and the reference to them is not canceled when these objects are no longer needed. The memory is still possible.
Of course, memory leaks in Java are not as dangerous as other programming languages such as C languages. Other memory is lost, will never be returned to the operating system, and in Java, we make unwanted objects are attached to the memory resources provided by the operating system as JVM. In theory, we will close the JVM, all assignments Memory resources will be returned to the operating system.
Fourth, how to detect memory leaks
The last important issue is how to detect Java's memory leaks. Currently, we usually use some tools to check the Memory leak problem of the Java program. There are several specializes in the market, and the basic working principle is similar, and all the information of all objects, all the information, etc., all the information, etc. of all objects, and analyze, and Visualization. Developers will determine whether the program has a memory leak problem based on this information. These tools include Optimizeit Profiler, JProbe Profiler, Jinsight, Rational's Purify, etc.
Below, we will briefly introduce the basic functions and working principles of Optimizeit.
Optimizeit Profiler version 4.11 supports the application, Applet, Servlet, and Romote Application four-class applications, and supports most types of JVM, including Sun JDK series, IBM JDK series, and JBuilder JVM. Also, the software is written by Java, so it supports a variety of operating systems. The OptimizeIt family also includes two tools for THREAD DEBUGER and CODE COVERAGEs, respectively, which are used to monitor running status and code coverage at runtime. When all of the parameters are set, we can run the verbated program in the Optimizeit environment. During the program running, Optimizeit can monitor the usage curve of the memory (similar to WinNT Task Manager, you can also pass WinNT Task Manager The Java consumes the memory to determine whether memory leaks), including the size of the JVM applications, and the actual memory size. In addition, during operation, we can suspend the operation of the program at any time, even forcibly calling the GC, allowing the GC to recycle. With the memory usage curve, we can understand the case where the program is used. This monitoring is also necessary for long-term operational applications, and it is easy to find memory leaks.
During the operation, we can also check the usage of memory from different perspectives, Optimizeit provides four ways:
Pile angle: This is a comprehensive perspective, we can understand all object information (quantity and type) in the heap, and perform statistics, sort, filtering. Understand the changes of related objects.
Method: From the perspective of the method, we can learn which methods are allocated in which methods are allocated, and their number.
Object Perspective: Given an object, through an object perspective, we can display all of its outlets and reference objects, we can understand all references to this object.
Quote: Given a root, by reference diagram, we can display all the references from the vertex.
During operation, we can observe the usage of memory at any time. In this way, we can quickly find objects that are not released for a long time, and no longer use. By checking the survival cycle of these objects, we confirm if it is a memory leak. In practice, looking for memory leaks is a very troublesome thing, it requires programmers to be clearer for the entire program, and requires rich debugging experience, but this process is very important for many key Java programs.
Five, summary
In summary, in Java programming, memory management is no longer concerned like a lot of programmers as Java, because Java's garbage collection mechanism can automatically manage memory recycling, programmers do not need to call additional functions to release RAM. But as more and more server programs use Java technology, such as JSP, Servlet, EJB, etc., servers are often run for a long time. In many embedded systems, the total amount of memory is very limited, and the leakage of memory becomes very The key is the key. Even if a small amount of leaks are run, long-term accumulation will also be the risk of the system faces crash. Here, I combined with the working principle of GC, some of the skills and methods related to memory management in Java program, allowing GC to run more efficient, more in line with applications:
1. The most basic recommendation is to release the reference to the useless object as soon as possible. Most programmers are using temporary variables that automatically set to NULL after exiting the activity domain (Scope). In this way, we must pay special attention to some complex object maps, such as arrays, queues, trees, and diagrams, etc., which are more complicated between these objects. For such objects, GC recovery they generally less efficient. If the program allows, the reference target that will not be used as soon as possible is NULL. This can accelerate the work of GC. 2, try to use the Finalize function as possible. The Finalize function is the opportunity to provide the programmakers to the programmaked object or resource. However, it will increase the workload of the GC, so try to recycle resources in Finalize mode.
3. If you need to use the images you use, you can use the Soft application type. It can save the picture in memory as much as possible, not cause OutofMemory.
4, pay attention to the collection data type, including data structures such as arrays, trees, diagrams, linkers, which are more complicated to GC. In addition, pay attention to some global variables, as well as some static variables. These variables are often easily caused by Dangling Reference, causing waste.
5. When the program has a certain wait time, the programmer can manually execute system.gc (), inform GC operation, but the Java language specification does not guarantee that the GC will execute. Use an incremental GC to shorten the pause time of the Java program.