我试图逐行读取一个大文本文件(7GB),从每一行中提取所有n-gram,并将它们存储在HashMap中。我从this code创建了以下类,并进行了一些修改:
public class NgExtract {
public List<String> ReturnNgrams(int order, String sent) {
List<String> ngs = new ArrayList<>();
String[] unigrams = sent.split(" ");
String ng;
for (int i = 0; i < unigrams.length - order + 1; i++) {
ng = BuildNg(unigrams, i, i + order);
if (!ngs.contains(ng.trim())) {
ngs.add(ng.trim());
}
}
return ngs;
}
public String BuildNg(String[] unigrams, int f, int l) {
StringBuilder ngStr = new StringBuilder();
for (int i = f; i < l; i++) {
ngStr.append(i > f ? " " : "").append(unigrams[i]);
}
return ngStr.toString();
}
}
我在while循环中读取了文本文件(见下文)。如果我在while循环中执行以下任何操作,则内存消耗会持续上升,直到我的计算机上没有可用内存(具有16 GB的RAM)。对于较小的文件(2-3 GB),程序终止但仍然消耗的内存量非常大(7-8 GB)。因此,我猜我在某处无法找到内存泄漏。另外,当我在循环中尝试诸如sentence.split(" ")
之类的方法时,程序很好地终止而没有内存问题。所以我几乎可以肯定问题在于NgExtract。
在循环内创建一个NgExtract实例,每个句子调用其ReturnNgrams()方法。
在循环外创建一个NgExtract实例,并在循环内为每个句子调用其ReturnNgrams()方法。
将ReturnNgrams定义为NgExtract的静态方法,并为循环内的每个句子调用它。
BufferedReader corpus = new BufferedReader(
new InputStreamReader(
new FileInputStream("path_2_corpus"), "UTF8"));
HashMap<String, Integer> allNgs = new HashMap();
while ((sentence = corpus.readLine()) != null) {
List<String> ngrams = //ReturnNgrams(sentence) approach 1, 2 or 3
//that I think leads to a (massive memory leak)
if (!allNgs.containsKey(ng)) {
allNgs.put(ng, 1);
} else if (allNgs.containsKey(ng)) {
int tmp = allNgs.get(ng);
tmp++;
allNgs.put(ng, tmp);
}
}