【问题标题】:Problem with Garbage Collection垃圾收集问题
【发布时间】:2011-05-05 06:35:55
【问题描述】:

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

我在完成之前在我的 LogCat 中得到了这个,调试器只是转到下一个方法:

DEBUG/dalvikvm(25743):GC_FOR_MALLOC 在 50 毫秒内释放了 2076 个对象/124280 个字节
调试/dalvikvm(25743):GC_FOR_MALLOC 在 52 毫秒内释放了 4 个对象/232 个字节
调试/dalvikvm(25743):GC_FOR_MALLOC 在 49 毫秒内释放了 142 个对象/46728 个字节
调试/dalvikvm(25743):GC_FOR_MALLOC 在 53 毫秒内释放了 0 个对象/0 个字节 调试/dalvikvm(25743):GC_FOR_MALLOC 在 39 毫秒内释放了 533 个对象/63504 个字节
调试/dalvikvm(25743):GC_FOR_MALLOC 在 50 毫秒内释放了 4 个对象/216 个字节
DEBUG/dalvikvm(25743):GC_EXTERNAL_ALLOC 在 40 毫秒内释放了 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);
    }
}

【问题讨论】:

  • 这听起来不像是很多内存。除了这些向量之外,其他地方也存在问题。
  • 我认为没有人可以在不查看代码...或至少查看数据结构的情况下提供有用的答案。
  • 好吧,我会贴一些课堂上的代码。也许我做了一些非常愚蠢的事情。从来没有真正关心过内存分配。
  • 99.9% 垃圾回收不是你的问题,因为它根本不会导致那种问题。它只会减慢你的程序,但不会导致它发生故障(除非你用尽了所有可用内存,但这会导致进程突然终止,而不是返回不完整的结果)。
  • mmmh,你在使用后关闭流吗?

标签: java android garbage-collection


【解决方案1】:

好吧,我现在得到了答案,这很尴尬……正如你们所说,这不是垃圾收集器的错。这是 LogCat 的错。并不是它打印出关于垃圾收集的那些行,而是它没有打印出我在循环完成时使用的 Log.i(tag, string) 的事实。 (在循环中我使用了 Log.v()。所以它实际上并没有给我不完整的结果,我只是无法看到完整的结果或者它实际上已经完成了。无论如何,我很抱歉占用了你的时间有时间了,我要感谢你们中那些试图提供帮助的人。

如果任何版主看到此内容,您可以关闭问题。否则我会尽快删除它。

【讨论】:

    【解决方案2】:

    我可以看出您正在犯一个系统性错误,但我不知道这是否是您的问题的原因。

    例如:

    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。您的代码似乎在这里和其他地方跳过了第零个标记。在processFLine 中,您使用tokens[1] 在不同的格式之间进行选择,结果您可以获得ArrayIndexOutOfBoundsException

    【讨论】:

    • 嗯,那是因为我对第一个(索引 0)不感兴趣,只是因为我的文件中有几行这样构建:v 0.000 1.000 0.000(例如)所以我想跳过'v'
    猜你喜欢
    • 2011-02-23
    • 2011-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-21
    • 2014-03-31
    相关资源
    最近更新 更多