垃圾收集问题

时间:2011-05-05 06:35:55

标签: java android garbage-collection

我编写了一个带有.obj文件的ObjectLoader,它给了我想要的东西。 我的问题是,当我处理大文件(甚至不是那么大,大约80kb)时,我最终 最终得不到所有信息,因为它会在一段时间后停止阅读。

我在完成之前在我的LogCat中得到了这个,并且debuger只是转到下一个方法:

  

DEBUG / dalvikvm(25743):GC_FOR_MALLOC在50ms内释放了2076个对象/ 124280字节
  DEBUG / dalvikvm(25743):GC_FOR_MALLOC在52ms内释放4个对象/ 232字节
  DEBUG / dalvikvm(25743):GC_FOR_MALLOC在49ms内释放了142个对象/ 46728个字节
  DEBUG / dalvikvm(25743):GC_FOR_MALLOC在53ms内释放了0个对象/ 0个字节   DEBUG / dalvikvm(25743):GC_FOR_MALLOC在39ms内释放533个对象/ 63504字节
  DEBUG / dalvikvm(25743):GC_FOR_MALLOC在50ms内释放4个对象/ 216个字节
  DEBUG / dalvikvm(25743):GC_EXTERNAL_ALLOC在40ms内释放了132个对象/ 26768个字节

换句话说,我猜很多垃圾收集。是因为我在代码中分配了大量内存吗?如果是这样,我是否需要阅读任何基础知识,或者您有任何其他建议吗?我正在使用4个向量,每个向量最后持有大约2K-3K对象。 编辑:实际上有7个向量,3个额外用于携带索引,但我仍然认为它不是那么多。

    private void readObj(InputStreamReader in) throws IOException
{
    BufferedReader reader = null;
    String line = null;

    reader = new BufferedReader(in);

    while ((line = reader.readLine()) != null)
    {
        Log.v(TAG, line);
        if (line.startsWith("f"))
        {
            faces++;
            processFLine(line);
        } else if (line.startsWith("vn"))
        {
            normals++;
            processVNLine(line);
        } else if (line.startsWith("vt"))
        {
            UVCoords++;
            processVTLine(line);
        } else if (line.startsWith("v"))
        {
            vertices++;
            processVLine(line);
        }
    }

}

private void processVNLine(String line)
{
    String[] tokens = line.split("[ ]+");
    int c = tokens.length;
    for (int i = 1; i < c; i++)
    {
        _vn.add(Float.valueOf(tokens[i]));
    }
}

private void processFLine(String line)
{
    String[] tokens = line.split("[ ]+");
    int c = tokens.length;

    if (tokens[1].matches("[0-9]+"))
    {
        caseFEqOne(tokens, c);
    }
    if (tokens[1].matches("[0-9]+/[0-9]+"))
    {
        caseFEqTwo(tokens, c);
    }
    if (tokens[1].matches("[0-9]+//[0-9]+"))
    {
        caseFEqOneAndThree(tokens, c);
    }
    if (tokens[1].matches("[0-9]+/[0-9]+/[0-9]+"))
    {
        caseFEqThree(tokens, c);
    }

}

private void caseFEqThree(String[] tokens, int c)
{
    for (int i = 1; i < c; i++)
    {
        Short s = Short.valueOf(tokens[i].split("/")[0]);
        s--;
        _vPointer.add(s);

        s = Short.valueOf(tokens[i].split("/")[1]);
        s--;
        _vtPointer.add(s);

        s = Short.valueOf(tokens[i].split("/")[2]);
        s--;
        _vnPointer.add(s);
    }
}

2 个答案:

答案 0 :(得分:1)

嗯,我现在得到了答案,这很令人尴尬......正如大家都说的那样,这不是垃圾收集者的错。这是LogCat的错。而不是它打印出关于垃圾收集的关于这一点的事实,它的事实是它没有打印出我在循环结束时使用的Log.i(标签,字符串)。 (在循环期间我使用了Log.v()。所以它确实没有给我不完整的结果,我只是无法看到完整的结果或它实际完成。好吧无论如何,我很抱歉接受你的这个时候,我要感谢那些试图提供帮助的人。

如果主持人看到这一点,您可以关闭此问题。否则我会尽快删除它。

答案 1 :(得分:0)

我可以看到你正在制造的一个系统性错误,但我不知道这是否是你问题的原因。

例如:

String[] tokens = line.split("[ ]+");
int c = tokens.length;
for (int i = 1; i < c; i++)
{
    _vn.add(Float.valueOf(tokens[i]));
}

在Java中,数组索引从零开始,然后上升到array.length - 1。您的代码似乎正在跳过第0个令牌,此处和其他位置。在processFLine您使用tokens[1]在不同格式之间进行选择的情况下,您可以获得ArrayIndexOutOfBoundsException