我有一个无法解决的性能问题。我正在编写一个解析巨大(> 2000 万行)文本文件并将某些信息存储在 Set 中的 Java 应用程序。我以每百万行的秒数来衡量性能。由于我需要大量内存,我通常使用 -Xmx6000m 和 -Xms4000m 运行程序。
如果我只是运行程序,它会在大约 6 秒内解析 100 万行。但是,经过一些性能调查后,我意识到,如果我在实际解析例程之前添加此代码,性能会增加到每 100 万行不到 3 秒:
BufferedReader br = new BufferedReader(new FileReader("graphs.nt"));
HashMap<String, String> foo = new HashMap<String, String>();
String line;
while ((line = br.readLine()) != null){
foo.put(line, "foo");
}
foo = null;
br.close();
br = null;
graphs.nt 文件大约有 900 万行。即使我不将 foo 设置为 null,性能仍然会提高,这主要是为了证明该地图实际上没有被程序使用。
其余代码完全不相关。我使用来自 openrdf sesame 的解析器来读取不同的(不是 graphs.nt)文件,并将提取的信息存储在由另一个对象创建的新 HashSet 中。在其余代码中,我创建了一个Parser 对象,我将一个Handler 对象传递给该对象。
这真的让我很困惑。我的猜测是,这以某种方式驱动 JVM 为我的程序分配更多内存,当我运行 top 时,我可以看到提示。如果没有 HashMap,它将分配大约 1 Gig 的内存。如果我初始化 HashMap,它将分配 > 2 Gigs。
我的问题是,这听起来是否合理。创建这么大的对象是否有可能为程序分配更多的内存以供以后使用?-Xmx 和 -Xms 不应该控制内存分配,还是有其他可能在这里起作用的参数?
我知道这似乎是一个奇怪的问题,而且信息很少,但这是我发现的与该问题相关的所有信息。如果有更多可能有用的信息,我非常乐意提供。