title: Java Garbage Collecting Reference Classes
body: <p>I'm testing how gc works with the classes in java.lang.ref package, just for study :)</p>
  
  <p>The following is my code.</p>
  
  <pre><code>public static void main(String [] args) {
  
      int mb = 1024*1024;
  
      //Getting the runtime reference from system
      Runtime runtime = Runtime.getRuntime();
  
      System.out.println("##### Heap utilization statistics [MB] #####");
      ArrayList&lt;Object&gt; sb = new ArrayList&lt;Object&gt;();
      for(int i =0; i &lt; 5000000; i++){
          sb.add(new Object());
          if( i % 1000 == 0) {
              System.out.println(i);
          }
      }
  
      SoftReference&lt;ArrayList&gt; wr = new SoftReference&lt;ArrayList&gt;(sb);
  
      // System.gc()
  
      //Print used memory
      System.out.println("Used Memory:"
          + (runtime.totalMemory() - runtime.freeMemory()) / mb);
  
      //Print free memory
      System.out.println("Free Memory:"
          + runtime.freeMemory() / mb);
  
      //Print total available memory
      System.out.println("Total Memory:" + runtime.totalMemory() / mb);
  
      //Print Maximum available memory
      System.out.println("Max Memory:" + runtime.maxMemory() / mb);
  }
  </code></pre>
  
  <p>It results:</p>
  
  <pre><code>Used Memory:95,
  Free Memory:28,
  Total Memory:123,
  Max Memory:247
  </code></pre>
  
  <p>And I undid comment on "System.gc()", and reran the code, the result was</p>
  
  <pre><code>Used Memory:1,
  Free Memory:122,
  Total Memory:123,
  Max Memory:247
  </code></pre>
  
  <p>Yeah, firstly, the instance of ArrayList was collected. As I know, Instances referenced only by SoftReference is softreachable, so collected when GC is really needed because of lack of left heap space. The left space of first result of the code was about 150(free mem 28 + left max mem 124). I don't understand why the instance of ArrayList was collected.</p>
  
  <p>And secondly, I ran the code with modifying:</p>
  
  <pre><code>sb.add(new Object()); -&gt; sb.add(new StringBuffer(i));
  </code></pre>
  
  <p>and It resulted:</p>
  
  <pre><code>Used Memory:245,
  Free Memory:2,
  Total Memory:247,
  Max Memory:247
  </code></pre>
  
  <p>Why is this different??</p>
  
  <p>And lastly, I ran the code again with modifying:
  from</p>
  
  <pre><code>SoftReference&lt;ArrayList&gt; wr = new SoftReference&lt;ArrayList&gt;(sb);
  </code></pre>
  
  <p>to</p>
  
  <pre><code>WeakReference&lt;ArrayList&gt; wr = new WeakReference&lt;ArrayList&gt;(sb);
  </code></pre>
  
  <p>It resulted:</p>
  
  <pre><code>Used Memory:245,
  Free Memory:2,
  Total Memory:247,
  Max Memory:247
  </code></pre>
  
  <p>I had guessed the instances of ArrayList were collected because the instances were referenced only by WeakReferece, so these were weakreachable. But they were not collected.</p>
  
  <p>I now assume that my understanding about the way of Reference's work was incorrect.</p>
  
  <p>Please anyone let me know why.</p>
  
  <p>Thx ^^</p>