Java内存泄漏示例

标签 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 用于生成乱码世界。

最佳答案

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

Here's the culprit:

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

进一步

Update: As of Java 1.7 update 6, string behaviour has changed so that taking a substring doesn't hold on to the original byte array. That's a bit of a blow to my contrived example, but the overall approach to finding the issue still holds.

关于Java内存泄漏示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27572324/

相关文章:

c++ - 增加内存使用量而不泄漏?

java - 如何在 Tomcat 中为 Java EE 应用程序实现套接字

java - OverlayLayout 不遵循焦点更改时的叠加顺序

java - 使用java创建一个没有数字重复的4位随机数

c++ cout和char-pointers,我缺少的指针

java - 从字符串中获取 Double 值

c - 如何将字符串数组附加到共享内存? C

C 线程和 curl 内存泄漏

java - Gson:如何反序列化具有类名的接口(interface)字段?

python - 难以理解 python 的 gc.garbage(用于跟踪内存泄漏)