user93796
user93796

Reputation: 18379

Java memory leak example

I came across this article about memory leak .It says that following code has memeory leak .But i dont understand how it is leaking memory.

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;
                 }
             }
         }
     }
 }

Refer following link for complete article:
What is the possible meory leak here?StringBuffer is used to generate Gibbersish worlds.

Upvotes: 0

Views: 469

Answers (1)

Elliott Frisch
Elliott Frisch

Reputation: 201399

You should have kept reading, it's the reference that's added to the goodWords list as discussed in the section titled Spoiler:

Here's the culprit:

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

And further on

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.

Upvotes: 1

Related Questions