title: Why GC doesn't run within the same method
body: <p>I'm playing with gc and found interesting situation when gc(I use parallel gc) isn't involved
  This is my code</p>
  
  <pre><code>public static void main(String[] args) {
         System.out.println(Runtime.getRuntime().freeMemory() / (1024 * 1024) + " free");
  
      String[] strings = new String[(40 * 1024 * 1024) / Integer.BYTES];
      System.out.println(strings.length);
  
      System.out.println(Runtime.getRuntime().freeMemory() / (1024 * 1024) + " free");
  
      strings = new String[(40 * 1024 * 1024) / Integer.BYTES];
      System.out.println(strings.length);
  
      System.out.println(Runtime.getRuntime().freeMemory() / (1024 * 1024) + " free");
  
      }
  </code></pre>
  
  <p>My Java version is :</p>
  
  <pre><code>java version "1.8.0_191"
  Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
  Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)
  </code></pre>
  
  <p>This program was involved with the following argc:</p>
  
  <pre><code>-Xmx64m -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps
  </code></pre>
  
  <p>This is the output:</p>
  
  <pre><code>59 free
  10485760
  19 free
  2019-06-09T14:53:18.868+0600: 0.105: [GC (Allocation Failure) [PSYoungGen: 1640K-&gt;480K(18944K)] 42600K-&gt;41448K(62976K), 0.0018199 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
  2019-06-09T14:53:18.870+0600: 0.107: [Full GC (Ergonomics) [PSYoungGen: 480K-&gt;0K(18944K)] [ParOldGen: 40968K-&gt;41339K(44032K)] 41448K-&gt;41339K(62976K), [Metaspace: 3033K-&gt;3033K(1056768K)], 0.0174681 secs] [Times: user=0.04 sys=0.00, real=0.02 secs] 
  2019-06-09T14:53:18.888+0600: 0.125: [GC (Allocation Failure) [PSYoungGen: 0K-&gt;0K(18944K)] 41339K-&gt;41339K(62976K), 0.0017270 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
  2019-06-09T14:53:18.889+0600: 0.126: [Full GC (Allocation Failure) [PSYoungGen: 0K-&gt;0K(18944K)] [ParOldGen: 41339K-&gt;41321K(44032K)] 41339K-&gt;41321K(62976K), [Metaspace: 3033K-&gt;3033K(1056768K)], 0.0140842 secs] [Times: user=0.03 sys=0.01, real=0.01 secs] 
  Heap
   PSYoungGen      total 18944K, used 491K [0x00000000feb00000, 0x0000000100000000, 0x0000000100000000)
    eden space 16384K, 3% used [0x00000000feb00000,0x00000000feb7afa0,0x00000000ffb00000)
    from space 2560K, 0% used [0x00000000ffd80000,0x00000000ffd80000,0x0000000100000000)
    to   space 2560K, 0% used [0x00000000ffb00000,0x00000000ffb00000,0x00000000ffd80000)
   ParOldGen       total 44032K, used 41321K [0x00000000fc000000, 0x00000000feb00000, 0x00000000feb00000)
    object space 44032K, 93% used [0x00000000fc000000,0x00000000fe85a6d0,0x00000000feb00000)
   Metaspace       used 3064K, capacity 4496K, committed 4864K, reserved 1056768K
    class space    used 336K, capacity 388K, committed 512K, reserved 1048576K
  Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
      at lightbox.GcWIthoutComp.main(GcWIthoutComp.java:11)
  </code></pre>
  
  <p>According to logs , JVM was not able to allocate memory for string second time ,but if I add JVM arg <code>-Xcomp</code> , it will work and provide this output </p>
  
  <pre><code>59 free
  10485760
  19 free
  2019-06-09T15:01:06.593+0600: 0.830: [GC (Allocation Failure) [PSYoungGen: 1982K-&gt;512K(18944K)] 42942K-&gt;41480K(62976K), 0.0008554 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
  2019-06-09T15:01:06.594+0600: 0.831: [Full GC (Ergonomics) [PSYoungGen: 512K-&gt;0K(18944K)] [ParOldGen: 40968K-&gt;411K(37376K)] 41480K-&gt;411K(56320K), [Metaspace: 3377K-&gt;3377K(1056768K)], 0.0100865 secs] [Times: user=0.01 sys=0.00, real=0.02 secs] 
  10485760
  20 free
  Heap
   PSYoungGen      total 18944K, used 1147K [0x00000000feb00000, 0x0000000100000000, 0x0000000100000000)
    eden space 16384K, 7% used [0x00000000feb00000,0x00000000fec1ed48,0x00000000ffb00000)
    from space 2560K, 0% used [0x00000000ffb00000,0x00000000ffb00000,0x00000000ffd80000)
    to   space 2560K, 0% used [0x00000000ffd80000,0x00000000ffd80000,0x0000000100000000)
   ParOldGen       total 44032K, used 41371K [0x00000000fc000000, 0x00000000feb00000, 0x00000000feb00000)
    object space 44032K, 93% used [0x00000000fc000000,0x00000000fe866c90,0x00000000feb00000)
   Metaspace       used 3399K, capacity 4500K, committed 4864K, reserved 1056768K
    class space    used 334K, capacity 388K, committed 512K, reserved 1048576K
  </code></pre>
  
  <p>As I understand compiled code is much comfortable for GC in terms of detecting unused memory.
  Moreover if I remove -Xcomp and move array creation to separate method it will not throw OOM exception:</p>
  
  <pre><code>public static void main(String[] args) {
          System.out.println(Runtime.getRuntime().freeMemory() / (1024 * 1024) + " free");
  
          allocate();
  
          System.out.println(Runtime.getRuntime().freeMemory() / (1024 * 1024) + " free");
          allocate();
          System.out.println(Runtime.getRuntime().freeMemory() / (1024 * 1024) + " free");
  
      }
  
      private static void allocate() {
          String[] strings = new String[(40 * 1024 * 1024) / Integer.BYTES];
          System.out.println(strings.length);
      }
  </code></pre>
  
  <p>My questions are:</p>
  
  <ol>
  <li><p>Why does -Xcomp solve problem with allocation as was shown above?</p></li>
  <li><p>Why does moving allocation to separate method solved my problem?</p></li>
  </ol>
  
  <p>If you have helpful links, please provide them in comments.</p>