“This is the fifth day of my participation in the Gwen Challenge.
JVM monitoring and diagnostics tools -GUI – JVM monitoring and diagnostics tools -GUI – MEMORY leaks
Memory leaks
Understanding and classification of memory leaks
What is a Memory leak?
Reachability analysis algorithms to determine whether an object is no longer used are essentially to determine whether an object is still referenced. In this case, there are many memory leaks due to the different implementation of the code (causing the JVM to mistakenly believe that the object is still in reference and cannot be reclaimed, causing memory leaks).
There are two main concerns:
- Is it still in use? is
- Is it still needed? no
Memory leak
Strictly speaking, a memory leak is when objects are no longer used by the program, but the GC cannot reclaim them. In practice, however, it is often poor practice (or negligence) that leads to long life cycles and even OOM, which can be called a “memory leak” in the broad sense.
Relationship between memory leakage and memory overflow
- If 512M of memory is allocated and 512M of memory is not recovered, then 512M of available memory is only allocated, as if part of the memory is leaked. In layman’s terms, a memory leak is a dog in the manger.
- Description Out of memory Does not have enough memory. Generally speaking, there are three pits in a toilet, two of them are standing in the pit (memory leak), and the last pit is left. The toilet means that the reception pressure is very high. At this time, two people come to the pit at once, and the pit space (memory leak) is not enough, and the memory leak becomes the memory overflow.
Relationship between memory leakage and memory overflow
Memory leaks increase, eventually leading to memory leaks.
Classification of leakage
- Frequently: Code that leaks memory is executed multiple times, leaking one block of memory each time it is executed.
- 2. To occur only under certain specific circumstances;
- One-time: Methods that leak memory are executed only once;
- Implicit leakage: holding memory until execution ends; It’s not technically a memory leak, because it’s eventually released,
legend
Eight cases of memory leaks in Java
Static collection class
Static collection classes, such as HashMap, LinkedList, and so on. If these containers are static, their declaration cycles are consistent with those of the JVM program, and objects in the containers cannot be released until the program ends, causing memory leaks. In simple terms, a long-life object has a reference to a short-life object, and although the short-life object is no longer in use, it cannot be reclaimed because the long-life object holds its reference.
public class MemoryLeak {
static List list = new ArrayList();
public void oomTests(a) {
Object obj = new Object();// Local variables
list.add(obj);
}
Copy the code
The singleton pattern
The singleton pattern causes a memory leak in a similar way to static collections. Because of the static nature of the singleton, its lifetime is as long as that of the JVM, so if a singleton holds a reference to an external object, that external object will not be recycled, causing a memory leak.
The inner class holds the outer class
An inner class holds an outer class if a method on an instance object of an outer class returns an instance object of an inner class. The inner class object is referenced for a long time, and even though the outer class instance object is no longer in use, because the inner class holds the instance object of the outer class, the outer class object will not be garbage collected, which can also cause a memory leak.
Various connections, such as database connections, network connections, IO connections, etc
Various connections, such as database connections, network connections, IO connections, etc. In the process of operation on the database, the first need to establish a connection with the database, when no longer used, you need to call the close method to release the connection with the database. Only after the connection is closed will the garbage collector reclaim the corresponding object. Otherwise, if a Connection, Statement, or ResultSet is not explicitly closed during database access, a large number of objects cannot be reclaimed, resulting in memory leaks.
Unreasonable scope of a variable
Unreasonable scope of a variable. In general, the definition of a variable is larger than its scope and is likely to cause memory leaks. On the other hand, if the object is not set to NULL in a timely manner, memory leaks are likely to occur.
Change the hash
Change the hash value. Once an object is stored in a HashSet, the fields in the object that computed the hash value cannot be changed. Otherwise, the modified hash of the object will be different from the hash originally stored in the HashSet. In this case, even if the Contains method retrieves the object from the HashSet using the current reference to the object as an argument, it will return the result that the object is not found, This also causes the current object to be unable to be individually removed from the HashSet collection, causing a memory leak. That’s why strings are immutable. We can safely store String as a HashSet, or as a HashMap key;
Cache leakage
Another common source of memory leaks is caches, which are easy to forget once you put object references into the cache. For example, when the project was put online, the application started very slowly until it crashed, because the code loaded the data in a table into the cache (memory). The test environment only had hundreds of data, but the production environment had millions of data.
For this problem, a WeakHashMap can be used to represent the cache. In this kind of Map, if there is no reference to the key other than its own, the Map will automatically discard the value.
Listeners and callbacks
Another common source of memory leaks is monitors and other callbacks, which can accumulate if clients register callbacks in the API you implement without showing cancellation.
The best way to ensure that a callback is immediately treated as garbage collection is to save only its weak references, such as them as keys in a WeakHashMap.
Memory leak case analysis
Case code
public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack(a) {
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(Object e) {
elements[size++] = e;
}
// There is a memory leak
public Object pop(a) {
if (size == 0)
throw new EmptyStackException();
return elements[--size];
}
private void ensureCapacity(a) {
if (size == elements.length)
elements = Arrays.copyOf(elements, size * 2 + 1); }}Copy the code
Analysis of the
There is nothing obviously wrong with this program, but it does have a memory leak, and as GC activity increases, or memory usage increases, the performance degradation of the program will show up, which can lead to leaks in severe cases, but these failures are relatively rare. The main problem with the code is the pop function, shown below in this diagram, assuming that the stack keeps growing, as shown below.
When a large number of POP operations are performed, the GC will not be released because the reference is not null, as shown in the figure below
As you can see from the figure above, if the stack grows first and shrinks, objects that pop from the stack will not be garbage collected. Even if programs no longer use objects in the stack, they will not be garbage collected because references to these objects are still stored in the stack, which is known as expired references. This memory leak is hidden.
The solution
public Object pop(a) {
if (size == 0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null;
return result;
}
Copy the code
Once the references expire, empty them, leaving the references empty.
conclusion
What is a memory leak? How did it happen? Finally, a simple case is used to demonstrate the problem of memory leakage. The next article will cover JVM monitoring and diagnostic tools -GUI, part 2.
Welcome everyone to pay attention to the public account (MarkZoe) to learn from each other and communicate with each other.