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?

4

3 回答 3

5

进行以下测试:删除该行

selection = input.next();

从循环。这将使它成为一个无限循环。如果你有内存泄漏,你会很快得到一个 OutOfMemoryError ,对吗?如果你没有得到一个,这意味着你没有任何内存泄漏。

您只是希望 GC 运行,但是当您认为它运行时它并没有运行。它在必要时运行。

于 2013-08-23T08:49:01.510 回答
4

此代码不应造成内存泄漏。您可以使用分析器查看内存的工作原理。JDK 提供的出色的 Visual VM (jvisualvm.exe) 可以向您展示如何在您的应用程序中处理内存和 GC。

首先,我更新了您的课程以在循环中自动运行。

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";
    }
}

接下来我运行它并附加分析器。这就是发生的事情。

jvisualvm 配置文件

如你看到的。内存使用量会增加,但 GC 会时不时地启动并清理。当使用的堆达到大约 35Mb 时,这似乎大约每 35 秒发生一次。

您似乎担心 GC 在对象符合条件时不会立即清理它们。这不是 GC 的工作方式。

于 2013-08-23T09:01:51.137 回答
-1

您可以尝试在循环后将列表设置为 null。

于 2013-08-23T08:56:17.510 回答