Easiest way to cause memory leak in Java? [duplica

2019-01-30 19:01发布

Possible Duplicate:
Creating a memory leak with Java

What's the easiest way to cause a java memory leak?

9条回答
Viruses.
2楼-- · 2019-01-30 19:33

From what I've read in the most voted answer, you are most probably asking for a C-like memory leak. Well, since there's garbagge collection, you can't allocate an object, loose all it's references and get it still occupying memory - that would be serious JVM bug.

On the other hand, you can happen to leak threads - which, of course, would cause this state, because you would have some thread running with it's references to objects, and you may loose the thread's reference. You can still get the Thread reference through the API - http://www.exampledepot.com/egs/java.lang/ListThreads.html

查看更多
放荡不羁爱自由
3楼-- · 2019-01-30 19:36

Here's a simple example

public class finalizer {
    @Override
        protected void finalize() throws Throwable {
        while (true) {
            Thread.yield();
        }
    }

    public static void main(String[] args) {
        while (true) {
            for (int i = 0; i < 100000; i++) {
                finalizer f = new finalizer();
            }

            System.out.println("" + Runtime.getRuntime().freeMemory() + " bytes free!");
        }
    }
}
查看更多
兄弟一词,经得起流年.
4楼-- · 2019-01-30 19:38
  1. Create a collection of objects at class scope
  2. Periodically add new objects to the collection
  3. Do not drop the reference to the instance of the class that holds the collection

Because there is always a reference to the collection and the instance of the object that owns the collection the Garbage Collector will never clean up that memory thus causing a "leak" over time.

查看更多
神经病院院长
5楼-- · 2019-01-30 19:42

Try this simple class:

public class Memory {
private Map<String, List<Object>> dontGarbageMe = new HashMap<String, List<Object>>();

public Memory() {
    dontGarbageMe.put("map", new ArrayList<Object>());
}

public void useMemInMB(long size) {
    System.out.println("Before=" + getFreeMemInMB() + " MB");

    long before = getFreeMemInMB();
    while ((before  - getFreeMemInMB()) < size) { 
        dontGarbageMe.get("map").add("aaaaaaaaaaaaaaaaaaaaaa");
    }

    dontGarbageMe.put("map", null);

    System.out.println("After=" + getFreeMemInMB() + " MB");
}

private long getFreeMemInMB() {
    return Runtime.getRuntime().freeMemory() / (1024 * 1024);
}

public static void main(String[] args) {
    Memory m = new Memory();
    m.useMemInMB(15);  // put here apropriate huge value
}
}
查看更多
叛逆
6楼-- · 2019-01-30 19:44

"A memory leak, in computer science (or leakage, in this context), occurs when a computer program consumes memory but is unable to release it back to the operating system." (Wikipedia)

The easy answer is: You can't. Java does automatic memory management and will free resources that are not needed for you. You can't stop this from happening. It will ALWAYS be able to release the resources. In programs with manual memory management, this is different. You cann get some memory in C using malloc(). To free the memory, you need the pointer that malloc returned and call free() on it. But if you don't have the pointer anymore (overwritten, or lifetime exceeded), then you are unfortunately incapable of freeing this memory and thus you have a memory leak.

All the other answers so far are in my definition not really memory leaks. They all aim at filling the memory with pointless stuff real fast. But at any time you could still dereference the objects you created and thus freeing the memory --> NO LEAK. acconrad's answer comes pretty close though as I have to admit since his solution is effectively to just "crash" the garbage collector by forcing it in an endless loop).

The long answer is: You can get a memory leak by writing a library for Java using the JNI, which can have manual memory management and thus have memory leaks. If you call this library, your java process will leak memory. Or, you can have bugs in the JVM, so that the JVM looses memory. There are probably bugs in the JVM, there may even be some known ones since garbage collection is not that trivial, but then it's still a bug. By design this is not possible. You may be asking for some java code that is effected by such a bug. Sorry I don't know one and it might well not be a bug anymore in the next Java version anyway.

查看更多
狗以群分
7楼-- · 2019-01-30 19:46

The following extremely contrived Box class will leak memory if used. Objects that are put into this class are eventually (after another call to put to be precise... provided the same object is not re-put into it.) inaccessible to the outside world. They cannot be dereferenced through this class, yet this class ensures they cannot be collected. This is a REAL leak. I know this is really contrived, but similar cases are possible to do by accident.

import java.util.ArrayList;
import java.util.Collection;
import java.util.Stack;

public class Box <E> {
    private final Collection<Box<?>> createdBoxes = new ArrayList<Box<?>>();
    private final Stack<E> stack = new Stack<E>();

    public Box () {
        createdBoxes.add(this);
    }

    public void put (E e) {
        stack.push(e);
    }

    public E get () {
        if (stack.isEmpty()) {
            return null;
        }
        return stack.peek();
    }
}
查看更多
登录 后发表回答