我遇到了关于内存泄漏的this article。它说下面的代码有记忆泄漏。但我不明白它是如何泄漏记忆的。
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import java.util.Random;
public class MemoryLeak
{
// Generates long lines of gibberish words.
static class GibberishGenerator implements Iterator<String>
{
private int MAX_WORD_LENGTH = 20;
private int WORDS_PER_LINE = 250000;
private String alphabet = ("abcdefghijklmnopqrstuvwxyz" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
public boolean hasNext() {
return true;
}
public String next() {
StringBuffer result = new StringBuffer();
for (int i = 0; i < WORDS_PER_LINE; i++) {
if (i > 0) { result.append(" "); }
result.append(generateWord(MAX_WORD_LENGTH));
}
return result.toString();
}
public void remove() {
// not implemented
}
private String generateWord(int maxLength) {
int length = (int)(Math.random() * (maxLength - 1)) + 1;
StringBuffer result = new StringBuffer(length);
Random r = new Random();
for (int i = 0; i < length; i++) {
result.append(alphabet.charAt(r.nextInt(alphabet.length())));
}
return result.toString();
}
}
// A "good" word has as many vowels as consonants and is more than two
// letters long.
private static String vowels = "aeiouAEIOU";
private static boolean isGoodWord(String word) {
int vowelCount = 0;
int consonantCount = 0;
for (int i = 0; i < word.length(); i++) {
if (vowels.indexOf(word.charAt(i)) >= 0) {
vowelCount++;
} else {
consonantCount++;
}
}
return (vowelCount > 2 && vowelCount == consonantCount);
}
public static void main(String[] args) {
GibberishGenerator g = new GibberishGenerator();
List<String> goodWords = new ArrayList<String>();
for (int i = 0; i < 1000; i++) {
String line = g.next();
for (String word : line.split(" ")) {
if (isGoodWord(word)) {
goodWords.add(word);
System.out.println("Found a good word: " + word);
break;
}
}
}
}
}
请参阅以下链接以获取完整文章:
这里可能存在的漏洞是什么?StringBuffer用于生成Gibbersish世界。
答案 0 :(得分:1)
您应该继续阅读,这是添加到goodWords
列表中的引用,如标题为Spoiler
的部分所述:
这是罪魁祸首:
String line = g.next(); for (String word : line.split(" ")) { if (isGoodWord(word)) { goodWords.add(word);
进一步
更新:从Java 1.7更新6开始,字符串行为已更改,因此获取子字符串不会保留原始字节数组。这对我的人为例子有点打击,但找到问题的整体方法仍然存在。