内存泄漏与阵列

时间:2012-10-26 14:05:45

标签: java android arrays heap-memory android-memory

我的Android应用程序存在一个非常奇怪的内存问题。 我的应用程序使用以下3个类:

public class RGB 
{
    public int R;
    public int G;
    public int B;
}

public class CMYK 
{
    public int C;
    public int M;
    public int Y;
    public int K;
}

public class COLOR 
{
    public String id;
    public CMYK cmyk = new CMYK();
    public RGB rgb = new RGB();

    public COLOR(String id, int c, int m, int y, int k, int r, int g, int b)
    {
        this.id = id;

        this.cmyk.C = c;
        this.cmyk.M = m;
        this.cmyk.Y = y;
        this.cmyk.K = k;

        this.rgb.R = r;
        this.rgb.G = g;
        this.rgb.B = b;
    }
}

然后在代码中我必须从文件加载2000种颜色(文件大约65K长度并且有2000条记录)并且放在资源文件夹中

public COLOR[] color_list = new COLOR[2000];
...
...
do
{
    s = reader.readLine();
    if (s != null)
    {
        String[] x = s.split(" ");
        COLOR c = new COLOR(x[0], Integer.parseInt(x[1]), Integer.parseInt(x[2]), Integer.parseInt(x[3]), Integer.parseInt(x[4]), Integer.parseInt(x[5]), Integer.parseInt(x[6]), Integer.parseInt(x[7]));
        color_list[j++] = c;
    }

} while (s != null);

此后应用程序将崩溃并停止工作。如果我删除do..while虽然一切正常,所以我认为我的阵列会越来越多,然后65K,我做错了什么?在Android LogCat上我已经达到了HEAP空间(26MB)!!!

祝你好运 GMG

3 个答案:

答案 0 :(得分:2)

尝试使用ArrayList而不是基本数组,它使内存管理变得更加容易。

答案 1 :(得分:2)

我认为代码不对OutOfMemoryException负责。也许还有其他领域你没有提及,但没有运行代码无法分辨。

但是,创建ID时可能会出现 small 泄漏。每当您从现有的String创建substring()时(基于String id = new String(x[0]); - 或正则表达式包中的方法),返回的字符串keeps an internal reference 到旧的:它只是一个围绕旧字符序列的薄包装,只是具有不同的开始和不同的长度。这意味着您最好像这样创建您的ID

String line;
Pattern pattern = Pattern.compile(" "); // Help the GC ;)

while ((line = in.readLine()) != null) {
    String[] data = pattern.split(line);

    // Ugly, but still better than a 8-args constructor
    RGB rgb = new RGB(data, 1, 3);
    CMYK cmyk = new CMYK(data, 4, 4);

    // the best would be a constructor like Color(String[8])
    colors[j++] = new Color(new String(data[0]), rgb, cmyk);
}

这样你就不会将整行留在内存中只是为了存储几个字符。

但是,这是一个优化,因为您声明您的文件是65KB,所以即使您将其全部保留在内存中,它也不会使您的应用程序崩溃。发布整个代码,以便我们可以运行和分析它。

顺便说一句,你可以用这种方式保存缩进级别:

{{1}}

我也改变了API(我发现这更舒服)

答案 2 :(得分:1)

没有错误就很难分辨,但我猜你得到的是IndexOutofBoundExceptions等等。您将数组初始化为2000个元素,但继续读取文件直到结束。如果有2001年的条目怎么办?然后你会吹过头。或者如果只有100个怎么办?然后你浪费了大量的空间。

像Ralgha所说,使用ArrayList,而不是数组。

对于文件解析,您可能需要考虑Scanner类。