1

I am working on a minesweeper-like game in Java and was noticing memory leaks occurring whenever I reset the board. I did a test below and found out that whenever I created a new object inside an ArrayList's add() method, the garbage collector would not dump the elements from the memory whenever I used the clear() method. Here's some code for reference:

import java.util.ArrayList;
import java.util.Scanner;

public class MemLeakTest {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        ArrayList<PointlessObject> list = new ArrayList();

        String selection = "1";

        while(selection.equals("1")){
            System.out.print("Type 1 to run test:");
            selection = input.next();
            System.out.println();

            //begin test
            if(selection.equals("1")){
                for(int i = 0; i<100000; i++){
                    list.add(new PointlessObject());
                }
            }
            list.clear(); // ArrayList elements remained in memory
        }
    }

}

class PointlessObject{
    String text;

    public PointlessObject(){
        text = "Stuff";
    }
}

What would be a better alternative to creating a long list of objects in which I can minimize memory leaks?

8
  • for garbage collection we generally call System.gc() method Commented Aug 23, 2013 at 8:39
  • How you know that still those objects are in memory? Commented Aug 23, 2013 at 8:39
  • 2
    How do you know there is a memory leak? What output are you getting that indicates that the program is retaining 100000 objects in your arraylist? Commented Aug 23, 2013 at 8:39
  • 4
    Garbage collection is not automatically run when you invoke list.clear(). As a matter of fact there is no grantee that it will be run exactly when it was grammatically called. GC will be executed by the JVM to remove the unused objects when it decides that it should be run. Thus your objects will live until this very time Commented Aug 23, 2013 at 8:41
  • 2
    This is not a memory leak, this is just how the gc works, as @Henry says garbage collection has a cost so it will be avoided until necessary. If you want to force it, you could call System.gc() but that is generally considered bad practice. If you have a memory requirement for your program you can specify it to the jvm using the system param -Xmx Commented Aug 23, 2013 at 8:55

3 Answers 3

5

Make the following test: remove the line

selection = input.next();

from the loop. This will make it an infinite loop. If you had a memory leak, you would get an OutOfMemoryError quickly, right? If you don't get one, this means that you don't have any memory leak.

You're simply expecting the GC to run, but it doesn't run when you think it runs. It runs when necessary.

Sign up to request clarification or add additional context in comments.

1 Comment

I didn't get an out of memory error. I guess I'll do what jimjim said and restrict the memory requirement for my program
4

This code should not create a memory leak. You can have a look at how memory works using a profiler. The excellent Visual VM provided (jvisualvm.exe) with the JDK can show you how memory and GC is handled in your app.

First I updated your class to run automatically in a loop.

package qwerky.sandbox;

import java.util.ArrayList;
import java.util.List;

public class MemLeakTest {

    public static void main(String[] args) throws Exception{

        List<PointlessObject> list = new ArrayList<PointlessObject>();

        while (true) {

            for(int i = 0; i<100000; i++){
                list.add(new PointlessObject());
            }

            Thread.sleep(1000);

            list.clear(); //ArrayList elements remained in memory

            Thread.sleep(1000);
        }
    }

}

class PointlessObject{
    String text;

    PointlessObject(){
        text = "Stuff";
    }
}

Next I ran it and attached the profiler. Here is what happens.

jvisualvm profile

As you can see. The memory usage builds up, but every now and again, the GC kicks in and tidies up. This seems to be happening about every 35 seconds, when the used heap gets to about 35Mb.

It seems like you are concerned that the GC doesn't clean up objects immediately when they are eligible. This isn't how GC works.

Comments

-1

You can try setting the list to null after your loop.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.