1

我的 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 条记录)并放在 assets 文件夹中

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

4

3 回答 3

2

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

于 2012-10-26T14:21:46.297 回答
2

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

但是,当您创建 ID 时,可能会有少量泄漏。每当您String从现有的(substring()基于 - 或 regex 包中的方法)创建一个时,返回的字符串都会保留对旧字符串的内部引用 :它只是旧字符序列的一个薄包装,只是具有不同的开始和不同长度。这意味着您最好像这样创建您的 ID

String id = new String(x[0]);

这样,您就不会为了存储几个字符而将整行保存在内存中。

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

顺便说一句,您可以通过这种方式保存缩进级别:

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

我还稍微更改了 API(我发现这更舒服)

于 2012-10-26T14:29:37.310 回答
1

没有错误很难说,但我假设你得到一个 IndexOutofBoundExceptions 或其他东西。您将数组初始化为 2000 个元素,但继续阅读您的文件,直到到达末尾。如果里面有 2001 个条目怎么办?然后你会吹过终点。或者如果只有 100 个呢?那你就浪费了很多空间。

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

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

于 2012-10-26T14:34:55.983 回答