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のレコードがあります)がアセットフォルダーに配置されます

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..を削除すると、アレイがますます65Kを超えると思いますが、何が間違っていますか? Android LogCat で、HEAP スペース (26MB) がいっぱいになりました!!!

よろしくお願いします GMG

4

3 に答える 3

2

そのコードが の責任を負うとは思いませんOutOfMemoryException。言及していない他のフィールドがあるかもしれませんが、コードを実行しないとわかりません。

ただし、ID を作成するときに小さなリークが発生する可能性があります。String既存のもの (substring()正規表現パッケージのベースまたはメソッドのいずれか) からを作成するときはいつでも、返された文字列は古いものへの内部参照を保持し ます。長さ。これは、次のように 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 に答える
2

基本的な配列の代わりにArrayListを使用してみてください。これにより、メモリ管理がはるかに簡単になります。

于 2012-10-26T14:21:46.297 に答える
1

エラーなしで判断するのは難しいですが、IndexOutofBoundExceptions か何かが発生していると思います。配列を 2000 要素に初期化しますが、最後に到達するまでファイルを読み続けます。その中に 2001 年のエントリがある場合はどうなりますか? その後、最後まで吹き飛ばします。それとも100人しかいない場合は?次に、大量のスペースを無駄にしました。

Ralghaが言ったように、配列ではなくArrayListを使用してください。

ファイルの解析には、Scannerクラスを検討することをお勧めします。

于 2012-10-26T14:34:55.983 に答える