Is there a memory leak in Java?

A memory leak is when an object or variable is held in memory that is no longer needed by a program.

Java has a garbage collection mechanism that ensures that when an object is no longer referenced, that is, orphaned, it is automatically removed from memory by the garbage collector.

If Java has garbage collection, why do you have memory leaks?

Some objects can’t be processed by the garbage collector, causing them to use up memory in the JVM, causing a memory leak.

Because Java uses a directed graph for garbage collection management, it eliminates the problem of reference loops. For example, if there are two objects that reference each other and they are unreachable to the root process, the GC can also reclaim them, as can be seen in the following code.

import java. io.IOException;
public class GarbageTest {

    public static void main(String[] args) throws IOException {
        try {
            // TODO Auto-generated method stub
            gcTest();
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("has exited gcTest!");
        System.in.read();
        System.in.read();
        System.out.println("out begin gc!");
        for (int i = 0; i < 100; i++) { System.gc(); System.in.read(); System.in.read(); }}private static void gcTest(a) throws IOException {
        System.in.read();
        System.in.read();
        Person p1 = new Person();
        System.in.read();
        System.in.read();
        Person p2 = new Person();
        p1.setMate(p2);
        p2.setMate(p1);
        System.out.println("before exit gctest!");
        System.in.read();
        System.in.read();
        System.gc();
        System.out.println("exit gctest!");
    }

    private static class Person {
        byte[] data = new byte[20000000];
        Person mate = null;

        public void setMate(Person other) { mate = other; }}}Copy the code

Memory leaks in Java: Long life cycle of object reference object holds a short life cycle is very possible memory leaks, object is no longer need room despite the short life cycle, but because of long life cycle object holds its reference that can’t be recycled, which is memory leaks in Java room scene, in layman’s terms, is the programmer might create an object, Memory leaks can occur in Java when the object is never used again, but the object is always referenced, that is, the object is useless but cannot be collected by the garbage collector.

For example, in a caching system, we load an object into the cache (in a global map object, for example) and then never use it again. The object’s value is referenced by the cache, but is no longer available.

To check for memory leaks in Java, make sure that the program executes all branches to the end of the program, and then see if an object is used. If not, the object is a memory leak.

If an external object instance of a class of the method returns an inner class instance of the object, the inner class object was cited for a long time, even if the external class instance objects no longer be used, but as a result of the inner class lasting external instance objects of a class, the external class object will not be garbage collected, this will cause memory leaks.

The following content from the Internet (one of the main characteristic is to empty stack elements, it is not completely removed from the array, but reduce the total number of storage, I can write better than this, when remove an element, by the way, let it disappear from the array will be the value of the element’s location can be set to null)

I really can’t think of a more classic example than that stack, so I have to cite someone else’s example. The following example is not what I thought of, but what I read in a book. Of course, if I didn’t read in a book, I might have thought of it myself after a while, but no one would believe me if I said I thought of it myself.

public class Stack {

    private Object[] elements = new Object[10];
    private int size = 0;

    public void push(Object e) {
        ensureCapacity();
        elements[size++] = e;
    }

    public Object pop(a) {
        if (size == 0) throw new EmptyStackException();
        return elements[--size];
    }

    private void ensureCapacity(a) {
        if (elements.length == size) {
            Object[] oldElements = elements;
            elements = new Object[2 * elements.length + 1];
            System.arraycopy(oldElements, 0, elements, 0, size); }}}Copy the code

The above principle should be very simple, if we add 10 elements to the heap, and then all pop up, even though the heap is empty, there is nothing we want, but this is an object that is not recyclable, this meets the two conditions of memory leak, useless, unrecyclable. But even if there is such a thing will not necessarily lead to what kind of consequences, if the heap of money is used less, also waste a few K memory and himself, anyway, our memory is on G, where will have what impact, and this thing will be recycled soon, what does it matter. Let’s look at two examples.

class Bad {

    public static Stack s = new Stack();
    static {
        s.push(new Object());

        s.pop(); // There is a memory leak on an object

        s.push(new Object());// The above object can be recycled, which is equivalent to self-healing}}Copy the code

Because it’s static, it lasts until the program exits, but we can also see that it has a self-healing function, which means that if you have 100 objects on your Stack at most, you’re going to have 100 objects that can’t be recycled at most, and that should make sense, The Stack holds 100 references inside, and the worst case scenario is that they’re all useless, because the old references disappear as soon as we start new ones!

Another case of a memory leak: When an object is stored in a HashSet, it cannot modify the fields in the object that are used to compute the hash value. Otherwise, the modified hash value of the object will be different from the hash value originally stored in the HashSet. In this case, Even if the Contains method retrieves an object from the HashSet collection using the current reference to the object as an argument, it returns a result that the object is not found, which makes it impossible to remove the current object from the HashSet collection separately, causing a memory leak.