【发布时间】:2018-04-13 14:16:45
【问题描述】:
我正在尝试创建一个程序,该程序根据几个 (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 中。所以在一个 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
我希望我遗漏了一些明显的东西,或者我误解了错误消息,无论哪种方式,如果有人能找到解决方案以便我能够生成更长的列表,我将非常感激.
【问题讨论】:
-
生成单词的时候不能直接写入文件吗?还是一堆字?我的意思是,将它们保存在内存中真的有好处吗?
-
我认为你是因为试图破解密码而受到编程之神的惩罚。
-
你给它最多 2G 的内存并生成 100M 的东西。除非这些东西中的每一个都占用不到 20 个字节,否则肯定会耗尽内存。请注意,所有 Java 对象在对这些对象的任何引用(包括对象引用的空间,如 ArrayList 的支持数组)之上至少占用 12 个字节。因此,内存不足听起来完全合理。
-
如果您分享生成密码变体的代码,我们或许可以提供帮助。
-
尝试分配 4G RAM 而不是 2G。在我看来,发生错误所花费的时间应该翻了一番。但它仍然是 1 分 9 秒,这是否意味着其他原因导致了问题?平安迪:)
标签: java heap-memory word-list