Details the causes of Java memory leaks

  • 2020-04-01 01:57:27
  • OfStack

Java memory recovery mechanism
Regardless of how memory is allocated in each language, the actual address of the allocated memory needs to be returned, that is, the first address of a pointer to a block of memory. Objects in Java are created using either new or reflection methods. These objects are created in the Heap and all objects are recovered by the Java virtual machine through the garbage collection mechanism. GC in order to be able to release the object correctly, can control the running state of each object, their application, references, citations, assignment and other condition monitoring, Java will manage memory using the method of real-time monitoring whether the object can be achieved, if not reached, then it is recycling, which can eliminate the problem of the reference cycle. In the Java language, there are two ways to determine whether a memory space meets the garbage collection criteria: one is to assign a null value to an object that has never been called again, and the other is to assign a new value to the object, thus reallocating the memory space.

Ii. Causes of Java memory leak
First, what is a memory leak? I often hear people talk about memory leaks, but few are clear about what they are. Memory leak is refers to the useless object (no longer used object) continues to occupy memory or the memory of the useless object can not be released in time, resulting in the waste of memory space is called memory leak. Sometimes memory leaks are not serious and subtle, so the developer doesn't know about them, but sometimes they can be serious and prompt you to be Out of memory.
So what is the root cause of Java memory leaks? A memory leak is likely to occur when a long-lived object holds a reference to a short-lived object. Although the short-lived object is no longer needed, it cannot be recovered because the long-lived object holds a reference to it. This is a memory leak scenario in Java. Specifically, there are the following categories:
1. Static collection class causes memory leak:
Memory leaks are most likely to occur with the use of HashMap, Vector, etc. These static variables have the same life cycle as the application, and all the objects they reference cannot be released, because they will always be referenced by Vector, etc.
Ex. :


Static Vector v = new Vector(10);
for (int i = 1; i<100; i++)
{
Object o = new Object();
v.add(o);
o = null;
}//

In this example, the Object Object is looped and put into a Vector. If only the reference itself is released (o=null), the Vector still references the Object, so the Object is not recyclable to the GC. Therefore, if the object is added to the Vector and must be removed from the Vector, the easiest way is to set the Vector object to null.

Remove () method is called after the properties of an object in the collection have been modified.

Ex. :


public static void main(String[] args)
{
Set<Person> set = new HashSet<Person>();
Person p1 = new Person(" Tang's monk ","pwd1",25);
Person p2 = new Person(" The Monkey King ","pwd2",26);
Person p3 = new Person(" Pig eight quit ","pwd3",27);
set.add(p1);
set.add(p2);
set.add(p3);
System.out.println(" A total of :"+set.size()+"  An element !"); //Result: total :3 elements!
p3.setAge(2); //Change the age of p3 when the value of hashcode corresponding to the p3 element changes
set.remove(p3); //It cannot be removed at this point, causing a memory leak
set.add(p3); //Add it again, and it worked
System.out.println(" A total of :"+set.size()+"  An element !"); //Result: total :4 elements!
for (Person person : set)
{
System.out.println(person);
}
}

3. Listener
In Java programming, we all need to deal with listeners. Usually an application will use many listeners. We will call methods such as addXXXListener() of a control to increase the listener, but we often do not remember to remove the listener when releasing the object, thus increasing the chance of memory leak.

4. Various connections
Database connections (datasource.getconnection ()), network connections (socket), and IO connections, for example, are not automatically collected by the GC unless they explicitly call their close () method to close the connection. The Resultset and Statement objects are not explicitly recycled, but the Connection must be explicitly recycled, because the Connection cannot be automatically recycled at any time, and the Resultset and Statement objects are immediately NULL once the Connection is recycled. However, if you use connection pooling, the situation is different. In addition to explicitly closing the connection, you must also explicitly close the Resultset Statement object (one of which is closed, and the other is closed), otherwise you will cause a large number of Statement objects to fail to be released, causing a memory leak. In this case, the connection is usually left in the try and the connection is released in the finally.

References to internal classes, external modules, etc
References to inner classes are one of the more easily forgotten, and failure to release can result in a series of subsequent class objects not being released. In addition, programmers should be careful of external module inadvertently reference, for example, programmer A is responsible for module A, called A method of module B, such as:
Public void registerMsg (Object b);
This call is made with great care. If an object is passed in, it is likely that module B will retain a reference to that object, and it is important to note whether module B provides the appropriate operation to remove the reference.

6. Singleton pattern
Incorrect use the singleton pattern is a common cause of memory leaks, singleton after be initialized in the JVM the entire life cycle of existence (in the way of static variables), if the singleton object holds the external object reference, then the external object will not be able to the normal recovery, the JVM lead to memory leaks, consider the following example:


class A{
public A(){
B.getInstance().setA(this);
}
....
}
//Class B USES the singleton pattern
class B{
private A a;
private static B instance=new B();
public B(){}
public static B getInstance(){
return instance;
}
public void setA(A a){
this.a=a;
}
//getter...
}

Obviously, B follows the singleton pattern, which holds A reference to an object of class A that cannot be recycled. Imagine what happens if A is A more complex object or collection type


Related articles: