Make heap exhaustion robust in app-image-methods test

It's need as we now throw OOME even when a small percentage of heap is
still free. This change ensures that the heap is fully exhausted, which
is expected by the test.

Bug: 144525957
Test: art/test/testrunner/testrunner.py
Change-Id: Id607423e7c250bdae9b05b9eb2f5b8571ca906e1
diff --git a/test/163-app-image-methods/src/Main.java b/test/163-app-image-methods/src/Main.java
index 33590fc..2b57634 100644
--- a/test/163-app-image-methods/src/Main.java
+++ b/test/163-app-image-methods/src/Main.java
@@ -62,9 +62,30 @@
         }
     }
 
+    private static int exhaustJavaHeap(Object[] data, int index, int size) {
+        Runtime.getRuntime().gc();
+        // Let out-of-bound exception be thrown if we go past the array length. This should
+        // never happen if the logic in the caller is right. The exception acts as an assertion.
+        while (size != 0) {
+            try {
+                data[index] = new byte[size];
+                ++index;
+            } catch (OutOfMemoryError oome) {
+                size /= 2;
+            }
+        }
+        return index;
+    }
+
     public static Object eatAllMemory() {
       Object[] result = null;
       int size = 1000000;
+      // Make sure that there is no reclaimable memory in the heap. Otherwise we may throw
+      // OOME to prevent GC thrashing, even if later allocations may succeed.
+      Runtime.getRuntime().gc();
+      System.runFinalization();
+      // NOTE: There is a GC invocation in exhaustJavaHeap. So we don't need one here.
+
       while (result == null && size != 0) {
           try {
               result = new Object[size];
@@ -74,14 +95,10 @@
       }
       if (result != null) {
           int index = 0;
-          while (index != result.length && size != 0) {
-              try {
-                  result[index] = new byte[size];
-                  ++index;
-              } catch (OutOfMemoryError oome) {
-                  size /= 2;
-              }
-          }
+          // Repeat to ensure there is no space left on the heap.
+          index = exhaustJavaHeap(result, index, size);
+          index = exhaustJavaHeap(result, index, /*size*/ 4);
+          index = exhaustJavaHeap(result, index, /*size*/ 4);
       }
       return result;
   }