我正在尝试创建一个程序,该程序根据几个(10-100)个原始输入单词生成单词列表。最终结果包含数百万行,可能数十亿行,每行一个单词。我已经走得足够远,我可以生成大约 500 万个单词,但是每当我运行会生成更多单词的东西时,比如 1 亿个左右,程序就会在大约 1 分 9 秒后崩溃。下面是错误输出:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3210)
at java.util.Arrays.copyOf(Arrays.java:3181)
at java.util.ArrayList.grow(ArrayList.java:265)
at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:239)
at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:231)
at java.util.ArrayList.add(ArrayList.java:462)
at wordlistgen.WordlistGen2.combineWords(WordlistGen2.java:129)
at wordlistgen.WordlistGen2.main(WordlistGen2.java:25)
/home/NAME/.cache/netbeans/8.1/executor-snippets/run.xml:53: Java
returned: 1
BUILD FAILED (total time: 1 minute 9 seconds)
我试图通过在netbeans.conf文件(运行Ubuntu 17.10)中输入-J-Xms1024m -J-Xmx2048m来增加Netbeans的堆大小,但错误仍然存在。
本质上,程序所做的是导入原始的10-100个单词:
static void importList() throws IOException{
ArrayList<String> rawList = new ArrayList<>();
try(BufferedReader br = new BufferedReader(new FileReader("textfile"))) {
for(String line; (line = br.readLine()) != null; ) {
rawList.add(line);
}
listOfLists.add(rawList);
loll++;
}
}
然后,使用一堆 for 循环,我用大写字母、末尾的数字、整个单词的子字符串等创建单词的新变体。这些单词存储在不同的数组列表中,而数组列表又存储在 ArrayList 的 ArrayList 中。所以在数组列表中。
当我完成单词的组合和操作后,我使用以下方法将整个最终的数组列表逐行输出到输出文件中:
static void outputFile(String fileName) throws IOException{
try (FileWriter writer = new FileWriter(fileName)) {
for(String str: finalList) {
writer.write(str +"n");
}
}
}
完整的代码可以在这里找到:https://pastebin.com/0fkvwYbx
我希望我错过了一些明显的东西,或者我误解了错误消息,无论哪种方式,如果有人能找到解决方案以便我能够生成更长的列表,我将不胜感激。
也许 ArrayList 不是适合您问题的 List 实现。 请参阅:何时使用 LinkedList 而不是 ArrayList?
我认为您在(引用)时不断遇到最坏的情况
add(E 元素) 是 O(1) 摊销的,但 O(n) 自数组以来的最坏情况 必须调整大小和复制
不仅在时间上效率低下,而且在内存上效率低下,因为您不断需要为ArrayLists复制巨大的后备阵列。 考虑使用 LinkedList,特别是因为您的代码似乎没有通过索引对列表进行随机访问