抱歉,我无法发布代码,但我有一个缓冲读取器,其缓冲区大小设置为 50000000 字节。它可以正常工作半小时,硬盘灯每两分钟左右闪烁一次,读取大量数据,然后在 CPU 处理数据时再次安静。但是大约半小时后(这是一个非常大的文件),硬盘开始抖动,就好像它一次读取一个字节一样。它仍然在同一个循环中,我想我检查了空闲内存以排除交换(堆大小是默认值)。
可能不会得到任何有用的答案,但值得一试。
好的,我已将堆大小更改为 768mb,但仍然没有。有大量可用内存,java.exe 仅使用大约 300mb。
现在我已经对其进行了分析,堆保持在 200MB 左右,远低于可用空间。CPU 保持在 50%。然而,硬盘开始疯狂地抖动。我不知道。我将用 c# 重写整个东西,这是我的解决方案。
这是代码(它只是一个丢弃的脚本,不漂亮):
BufferedReader s = null;
HashMap<String, Integer> allWords = new HashMap<String, Integer>();
HashSet<String> pageWords = new HashSet<String>();
long[] pageCount = new long[78592];
long pages = 0;
Scanner wordFile = new Scanner(new BufferedReader(new FileReader("allWords.txt")));
while (wordFile.hasNext()) {
allWords.put(wordFile.next(), Integer.parseInt(wordFile.next()));
}
s = new BufferedReader(new FileReader("wikipedia/enwiki-latest-pages-articles.xml"), 50000000);
StringBuilder words = new StringBuilder();
String nextLine = null;
while ((nextLine = s.readLine()) != null) {
if (a.matcher(nextLine).matches()) {
continue;
}
else if (b.matcher(nextLine).matches()) {
continue;
}
else if (c.matcher(nextLine).matches()) {
continue;
}
else if (d.matcher(nextLine).matches()) {
nextLine = s.readLine();
if (e.matcher(nextLine).matches()) {
if (f.matcher(s.readLine()).matches()) {
pageWords.addAll(Arrays.asList(words.toString().toLowerCase().split("[^a-zA-Z]")));
words.setLength(0);
pages++;
for (String word : pageWords) {
if (allWords.containsKey(word)) {
pageCount[allWords.get(word)]++;
}
else if (!word.isEmpty() && allWords.containsKey(word.substring(0, word.length() - 1))) {
pageCount[allWords.get(word.substring(0, word.length() - 1))]++;
}
}
pageWords.clear();
}
}
}
else if (g.matcher(nextLine).matches()) {
continue;
}
words.append(nextLine);
words.append(" ");
}