title: Tips optimizing Java code
body: <p>So, I've written a spellchecker in Java and things work as they should. The only problem is that if I use a word where the max allowed distance of edits is too large (like say, 9) then my code runs out of memory. I've profiled my code and dumped the heap into a file, but I don't know how to use it to optimize my code. </p>
  
  <p>Can anyone offer any help? I'm more than willing to put up the file/use any other approach that people might have. </p>
  
  <p>-Edit-</p>
  
  <p>Many people asked for more details in the comments. I figured that other people would find them useful, and they might get buried in the comments. Here they are:</p>
  
  <ul>
  <li><p>I'm using a Trie to store the words themselves.</p></li>
  <li><p>In order to improve time efficiency, I don't compute the Levenshtein Distance upfront, but I                 calculate it as I go. What I mean by this is that I keep only two rows of the LD table in memory. Since a Trie is a prefix tree, it means that every time I recurse down a node, the previous letters of the word (and therefore the distance for those words) remains the same. Therefore, I only calculate the distance with that new letter included, with the previous row remaining unchanged.</p></li>
  <li><p>The suggestions that I generate are stored in a HashMap. The rows of the LD table are stored in ArrayLists. </p></li>
  </ul>
  
  <p>Here's the code of the function in the Trie that leads to the problem. Building the Trie is pretty straight forward, and I haven't included the code for the same here. </p>
  
  <pre><code>/*
   * @param letter: the letter that is currently being looked at in the trie
   *        word: the word that we are trying to find matches for
   *        previousRow: the previous row of the Levenshtein Distance table
   *        suggestions: all the suggestions for the given word
   *        maxd: max distance a word can be from th query and still be returned as suggestion
   *        suggestion: the current suggestion being constructed
   */
  
  
  public void get(char letter, ArrayList&lt;Character&gt; word, ArrayList&lt;Integer&gt; previousRow, HashSet&lt;String&gt; suggestions, int maxd, String suggestion){
  
  // the new row of the trie that is to be computed.
  ArrayList&lt;Integer&gt; currentRow = new ArrayList&lt;Integer&gt;(word.size()+1);
  currentRow.add(previousRow.get(0)+1);
  
  int insert = 0;
  int delete = 0;
  int swap = 0;
  int d = 0;
  
  for(int i=1;i&lt;word.size()+1;i++){
      delete = currentRow.get(i-1)+1;
      insert = previousRow.get(i)+1;
  
      if(word.get(i-1)==letter)
      swap = previousRow.get(i-1);
      else
      swap = previousRow.get(i-1)+1;
  
      d = Math.min(delete, Math.min(insert, swap));
      currentRow.add(d);
  }
  
  // if this node represents a word and the distance so far is &lt;= maxd, then add this word as a suggestion
  if(isWord==true &amp;&amp; d&lt;=maxd){
      suggestions.add(suggestion);
      }
  
  // if any of the entries in the current row are &lt;=maxd, it means we can still find possible solutions. 
  // recursively search all the branches of the trie
  for(int i=0;i&lt;currentRow.size();i++){
      if(currentRow.get(i)&lt;=maxd){
      for(int j=0;j&lt;26;j++){
          if(children[j]!=null){
          children[j].get((char)(j+97), word, currentRow, suggestions, maxd, suggestion+String.valueOf((char)(j+97))); 
          }
      }
      break;
      }   
  }
  }
  </code></pre>