Java内存泄漏示例

时间:2014-12-19 19:01:56

标签: java string memory-leaks garbage-collection out-of-memory

我遇到了关于内存泄漏的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世界。

1 个答案:

答案 0 :(得分:1)

您应该继续阅读,这是添加到goodWords列表中的引用,如标题为Spoiler的部分所述:

  

这是罪魁祸首:

String line = g.next();
for (String word : line.split(" ")) {
    if (isGoodWord(word)) {
        goodWords.add(word);

进一步

  

更新:从Java 1.7更新6开始,字符串行为已更改,因此获取子字符串不会保留原始字节数组。这对我的人为例子有点打击,但找到问题的整体方法仍然存在。