import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class R {

    public static void main(String[] args) {
        List<String> options = new ArrayList<>();
        Collections.addAll(options,
                "java",
                "-ea", 
                "-esa", 
                "-server", 
                "-Xcomp", 
                "-XX:CompileThreshold=100", 
                "-XX:+CreateCoredumpOnCrash", 
                "-XX:MaxRAMFraction=8", 
                "-XX:-TieredCompilation", 
                "-XX:+UnlockExperimentalVMOptions", 
                "-XX:+UseG1GC",
                "-Xmx20m",
                "-Xmn10m",
                "-Xlog:gc=info",
                "-XX:G1HeapRegionSize=1m"
        );

        options.add(Alloc.class.getName());
        ProcessBuilder pb = new ProcessBuilder(options);

        try {
            int v ;
	    long count = 0;
            do {
                Process p = pb.start();
                BufferedReader std = new BufferedReader(new InputStreamReader(p.getInputStream()));
                BufferedReader err = new BufferedReader(new InputStreamReader(p.getErrorStream()));
                v = p.waitFor();
                String line;
                while((line = std.readLine()) != null) {
                    System.out.println(line);
                }
                while((line = err.readLine()) != null) {
                    System.out.println(line);
                }
                System.out.println("########## EXIT CODE:" + v);
                System.out.println("Count:" + ++count);
            } while(v == 1);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    // Simple class to be executed in separate VM.
    static class Alloc {

        public static final int CHUNK = 1024;
        public static ArrayList<Object> arr = new ArrayList<>();

        public static void main(String[] args) {
            try {
                while (true) {
                    arr.add(new byte[CHUNK]);
                }
            } catch (OutOfMemoryError oome) {
            }
            while (true) {
                arr.add(new byte[CHUNK]);
            }
        }
    }

  public class Alloc2 extends Thread {
    public static long wt;
    
    public final int CHUNK = 16;
    public ArrayList<Object> arr = new ArrayList<>();

    public static Alloc2[] array = new Alloc2[1];

    private boolean w;
    
    Alloc2(boolean w) {
      this.w = w;
    }
    
    public void run() {
      if (w) {
        try {
          Thread.sleep(wt);
        } catch (InterruptedException e) {
        }
      }
          
      while (true) {
        try {
          while (true) {
            arr.add(new byte[CHUNK]);
          }
        } catch (OutOfMemoryError oome) {
          if (w) {
            continue;
          } else {
            break;
          }
        }
      }
      while (true) {
        arr.add(new byte[CHUNK]);
      }
    }
    
    public static void main(String[] args) throws Exception {
      wt = Long.parseLong(args[0]);
      
      for (int i = 0; i < array.length; i++) {
        array[i] = new Alloc2(true);
        array[i].setDaemon(true);
        array[i].start();
      }

      Thread.sleep(1000);
      
      new Alloc2(false).run();
    }
  }
}
