【问题标题】:Memory leak when counting the number of occurrences of the user IDs in the user logs计算用户日志中用户 ID 的出现次数时发生内存泄漏
【发布时间】:2015-10-18 17:45:35
【问题描述】:

我需要统计用户日志中用户 ID 的出现次数。 我有 10 个日志文件(每个都有 2-3 GB)。每个文件都有很长的行,其中我只需要一个用户 ID 值。我编写了代码(见下文),不幸的是,当我运行它时,我看到非常强大的内存使用并得到错误“java.lang.OutOfMemoryError:GC 开销限制超出”。 请帮我更正我的代码...

public static void main(String[] args) throws IOException {

    Path ptIn = new Path("/user/test");
    FileSystem fs = FileSystem.get(new Configuration());
    FileStatus[] lf = fs.listStatus(ptIn);

    LinkedHashMap<String, Integer> map = new LinkedHashMap<String, Integer>();

    for (int i = 0; i < lf.length; i++) {

        BufferedReader br = new BufferedReader(new InputStreamReader(fs.open(lf[i].getPath())));

        String line = null;

        while ((line = br.readLine()) != null) {

            String key = line.split("\\t")[2].intern();

            if (map.containsKey(key)) {
                map.put(key, map.get(key) + 1);
            } else {
                map.put(key, 1);
            }
        }

        br.close();
        br = null;
    }

    Path ptOut = new Path("/user/test/test.result.txt");
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fs.create(ptOut, true)));

    for (String key : map.keySet()) {
        bw.write(key + "\t" + map.get(key) + "\n");
    }

    bw.close();
    bw = null;
    map.clear();
}

【问题讨论】:

  • 你为什么要intern密钥?
  • 您必须为此使用 Java 吗?因为cat | cut | sort | uniq 命令链肯定会快很多(如果您使用的是某种形式的 Unix)。
  • @Mureinik 我不太懂java 这是我解决问题的尝试(这里我可能错了)
  • @biziclop 不幸的是(在这个领域)需要java
  • @Shamany 没有回答 Mureinik 的问题。你为什么叫实习生()?这个想法从何而来,为什么你认为它是一个好想法?你明白 intern() 是做什么的吗?你读过它的文档吗?

标签: java string file hashmap


【解决方案1】:

有两个地方可以积累记忆 - 在地图变量中 - 您将太多不同的“用户”放到表中 - 在行变量中 - 一个文件包含的行太长而无法存储在内存中 - 使用一些“用户”值解析器逐个字符地读取字符

【讨论】:

  • 为了改进您的答案,请提供有关如何完成此操作的示例。还建议如何设置内存
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-13
  • 2020-11-29
  • 1970-01-01
  • 2013-11-09
  • 2013-11-02
  • 1970-01-01
相关资源
最近更新 更多