How Java is managing memory
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, programmers need to request memory space for each object through the keyword new (except for the base type), and all objects allocate space in the heap. In addition, the release of the object is determined and executed by the GC. In Java, the allocation of memory is done by the program, and the release of memory is a GC, the two lines of the method does simplify the work of the programmer. But it also adds to the JVM's work. This is one of the reasons why the Java program is running slower. Because, in order for the GC 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.
To better understand how the GC works, we can consider the object as a vertex of the directed graph, consider the reference relationship as a directed edge of the graph, and have a directed edge from the referrer to the cited object. In addition, each thread object can be used as the starting vertex of a graph, for example, when most programs are executed from the main process, the graph is a root tree that starts with the main process vertex. In this graph, the object that the root vertex can reach is a valid object, and the GC will not reclaim those objects. If an object (connected sub-graph) and this root vertex are unreachable (note that the graph is a forward graph), then we think that this (these) objects are no longer referenced and can be recycled by GC.
Below, let's give an example of how memory management is represented by a graph. For every moment of the program, we have a graph of graphs that represent the memory allocations of the JVM. On the right, the left program runs to line 6th.
Java uses a graph-like approach to memory management, which eliminates the problem of reference loops, such as having three objects and referencing each other, so that GC can reclaim them as long as they are unreachable from the root process. The advantage of this approach is that the precision of managing memory is high, but the efficiency is low. Another common memory management technique is the use of counters, such as the COM model, which uses counter-mode management artifacts, which are low-precision rows (difficult to handle circular references) compared to a forward graph, but perform efficiently.
Back to top of page
What is a memory leak in Java
Below, we can describe what a memory leak is. 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 accessible, that is, in the graph, the existence of the path can be connected to it, and secondly, 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.
In C + +, memory leaks are larger in scope. Some objects are allocated memory space, and then unreachable, because there is no GC in C + +, the memory will never be returned. In Java, these unreachable objects are collected by the GC, so programmers do not need to consider this part of the memory leak.
Through the analysis, we learned that for C + +, programmers need to manage their own edges and vertices, and for Java programmers only need to manage the edge (do not need to manage the release of vertices). In this way, Java improves the efficiency of programming.
So, with the above analysis, we know that there is also a memory leak in Java, but the scope is smaller than C + +. Because Java is guaranteed by the language that any object is accessible, all unreachable objects are managed by the GC.
For programmers, GC is basically transparent and invisible. Although we have only a few functions that can access the GC, such as the function System.GC (), which 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, a GC's thread has 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. Unless the GC's execution affects the performance of the application on certain occasions, such as a web-based real-time system, such as a network game, where the user does not want the GC to suddenly interrupt application execution for garbage collection, then we need to adjust the GC's parameters so that the GC can free up memory in a gentle manner. For example, by decomposing garbage collection into a series of small steps, the sun-provided hotspot JVM supports this feature.
A simple example of a memory leak is given below. In this example, we iterate over the object and put the requested object into a vector, and if we just release the reference itself, then the vector still references the object, so the object is not recyclable to the 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 (int i=1;i<100; 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.
Back to top of page
How to detect memory leaks
The last important question is how to detect a Java memory leak. Currently, we often use tools to check the memory leaks 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.
Below, we will briefly describe the basic functions and working principles of Optimizeit.
Optimizeit Profiler version 4.11 supports Application,applet,servlet and Romote application four class applications and can support most types of JVMs, including the Sun JDK series, IBM's JDK series, and JBuilder's JVM. And, the software is written by Java, so it supports multiple operating systems. The Optimizeit series also includes the thread debugger and code coverage two tools, which are used to monitor the state of the threads at runtime and the coverage of codes, respectively.
When all parameters are set, we can run the program under the Optimizeit environment, and in the process of running the program, Optimizeit can monitor the memory usage curve (such as), including the size of the heap that the JVM is requesting, and the actual memory size used. In addition, during the operation, we can pause the program at any time, or even forcibly call the GC, so that the GC for memory recovery. With the memory usage curve, we can understand the overall memory usage of the program. This monitoring is necessary for long-running applications and it is also easy to detect memory leaks.
In the process of operation, we can also look at the use of memory from different perspectives, Optimizeit provides four ways:
- Heap perspective. This is a comprehensive perspective, we can understand all the object information in the heap (quantity and kind), and statistics, sorting, filtering. Learn about changes to related objects.
- Method perspective. From a methodological perspective, we can tell what kinds of objects are allocated in which methods, and how many they are.
- Object perspective. Given an object, through the object perspective, we can display all of its out-of-reference and in-reference objects, and we can understand all the referential relationships of this object.
- Reference graph. Given a root, by referencing the graph, we can display all the out references from that vertex.
In the process of running, we can always observe the use of memory, in this way, we can quickly find those who have not been released for a long time, and no longer use the object. We check the life cycle of these objects to see if they are memory leaks. In practice, looking for memory leaks is a very troublesome thing, it requires the programmer to the entire code of the program is relatively clear, and requires extensive debugging experience, but this process for many key Java programs are very important.
In summary, Java also has a memory leak problem, the main reason is that some objects are not used, but they are still referenced. To solve these problems, we can check the memory leaks through software tools, the main principle of the inspection is to expose all the objects in the heap, let the programmer look for the useless but still referenced objects
Ext.: http://www.ibm.com/developerworks/cn/java/l-JavaMemoryLeak/
Java memory leaks