gt:         for (int i = 0; i < objects.length; i++) {
context: /*
   * Copyright (C) 2007 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package android.core;
  
  import android.test.suitebuilder.annotation.LargeTest;
  import android.test.suitebuilder.annotation.MediumTest;
  import android.test.suitebuilder.annotation.SmallTest;
  import android.util.Log;
  import android.test.suitebuilder.annotation.Suppress;
  import dalvik.system.VMRuntime;
  import junit.framework.TestCase;
  
  import java.lang.ref.PhantomReference;
  import java.lang.ref.ReferenceQueue;
  import java.lang.ref.SoftReference;
  import java.lang.ref.WeakReference;
  import java.util.LinkedList;
  import java.util.Random;
  
  
  public class HeapTest extends TestCase {
  
      private static final String TAG = "HeapTest";
  
      /**
       * Returns a WeakReference to an object that has no
       * other references.  This is done in a separate method
       * to ensure that the Object's address isn't sitting in
       * a stale local register.
       */
      private WeakReference<Object> newRef() {
          return new WeakReference<Object>(new Object());
      }
  
      /**
       * Allocates the specified number of bytes. This is done in a separate method
       * to ensure that the Object's address isn't sitting in a stale local register.
       */
      private void allocateMemory(int size) {
          byte[] b = new byte[size];
      }
  
      @MediumTest
      public void testMinimumHeapSize() throws Exception {
          VMRuntime r = VMRuntime.getRuntime();
          final boolean RUN_FLAKY = false;
  
          long origSize = r.getMinimumHeapSize();
          if (RUN_FLAKY) {
              /* Check that the default value is zero.  This will break if anyone
               * in this process sets the minimum heap size to a positive value
               * before calling this test.
               */
              assertTrue(origSize == 0);
          }
  
          long size = 4 * 1024 * 1024;
          long oldSize = r.setMinimumHeapSize(size);
          assertTrue(oldSize == origSize);
  
          long newSize = r.getMinimumHeapSize();
          /* This will fail if the maximum heap size (-Xmx) is smaller than 4MB.
           */
          assertTrue(newSize == size);
  
          /* Make sure that getting the size doesn't change anything.
           */
          newSize = r.getMinimumHeapSize();
          assertTrue(newSize == size);
  
          /* This test is flaky; if the heap is already large and fragmented,
           * it can fail.  It can also fail if another thread causes a GC
           * at the wrong time.
           */
          if (RUN_FLAKY) {
              /* Increase the minimum size, allocate a big object, and make sure that
               * a GC didn't happen.
               */
              WeakReference ref = newRef();
              assertNotNull(ref.get());
  
              r.setMinimumHeapSize(8 * 1024 * 1024);
              allocateMemory(4 * 1024 * 1024);
  
              /* If a GC happened, this reference will be null.
               */
              assertNotNull(ref.get());
          }
  
          /* Restore the original setting.
           */
          r.setMinimumHeapSize(origSize);
          newSize = r.getMinimumHeapSize();
          assertTrue(newSize == origSize);
  
          /* Clean up any large stuff we've allocated,
           * and re-establish the normal utilization ratio.
           */
          Runtime.getRuntime().gc();
      }
  
      private static void makeRefs(Object objects[], SoftReference<Object> refs[]) {
          for (int i = 0; i < objects.length; i++) {
              objects[i] = (Object) new byte[8 * 1024];
              refs[i] = new SoftReference<Object>(objects[i]);
          }
      }
  
      private static <T> int checkRefs(SoftReference<T> refs[], int last) {
          int i;
          int numCleared = 0;
          for (i = 0; i < refs.length; i++) {
              Object o = refs[i].get();
              if (o == null) {
                  numCleared++;
              }
          }
          if (numCleared != last) {
              Log.i(TAG, "****** " + numCleared + "/" + i + " cleared ******");
          }
          return numCleared;
      }
  
      private static void clearRefs(Object objects[], int skip) {
          for (int i = 0; i < objects.length; i += skip) {
              objects[i] = null;
          }
      }
  
      private static void clearRefs(Object objects[]) {
          clearRefs(objects, 1);
      }
  
      private static <T> void checkRefs(T objects[], SoftReference<T> refs[]) {
          boolean ok = true;
  
          for (int i = 0; i < objects.length; i++) {
              if (refs[i].get() != objects[i]) {
                  ok = false;
              }
          }
          if (!ok) {
              throw new RuntimeException("Test failed: soft refs not cleared");
          }
      }
  
      @MediumTest
      public void testGcSoftRefs() throws Exception {
          final int NUM_REFS = 128;
  
          Object objects[] = new Object[NUM_REFS];
          SoftReference<Object> refs[] = new SoftReference[objects.length];
  
          /* Create a bunch of objects and a parallel array
           * of SoftReferences.
           */
          makeRefs(objects, refs);
          Runtime.getRuntime().gc();
  
          /* Let go of some of the hard references to the objects so that
           * the references can be cleared.
           */
          clearRefs(objects, 3);
  
          /* Collect all softly-reachable objects.
           */
          VMRuntime.getRuntime().gcSoftReferences();
          Runtime.getRuntime().runFinalization();
  
          /* Make sure that the objects were collected.
           */
          checkRefs(objects, refs);
  
          /* Remove more hard references and re-check.
           */
          clearRefs(objects, 2);
          VMRuntime.getRuntime().gcSoftReferences();
          Runtime.getRuntime().runFinalization();
          checkRefs(objects, refs);
  
          /* Remove the rest of the references and re-check.
           */
          /* Remove more hard references and re-check.
           */
          clearRefs(objects);
          VMRuntime.getRuntime().gcSoftReferences();
          Runtime.getRuntime().runFinalization();
          checkRefs(objects, refs);
      }
  
      public void xxtestSoftRefPartialClean() throws Exception {
          final int NUM_REFS = 128;
  
          Object objects[] = new Object[NUM_REFS];
          SoftReference<Object> refs[] = new SoftReference[objects.length];
  
          /* Create a bunch of objects and a parallel array
          * of SoftReferences.
          */
          makeRefs(objects, refs);
          Runtime.getRuntime().gc();
  
          /* Let go of the hard references to the objects so that
          * the references can be cleared.
          */
          clearRefs(objects);
  
          /* Start creating a bunch of temporary and permanent objects
          * to drive GC.
          */
          final int NUM_OBJECTS = 64 * 1024;
          Object junk[] = new Object[NUM_OBJECTS];
          Random random = new Random();
  
          int i = 0;
          int mod = 0;
          int totalSize = 0;
          int cleared = -1;
          while (i < junk.length && totalSize < 8 * 1024 * 1024) {
              int r = random.nextInt(64 * 1024) + 128;
              Object o = (Object) new byte[r];
              if (++mod % 16 == 0) {
                  junk[i++] = o;
                  totalSize += r * 4;
              }
              cleared = checkRefs(refs, cleared);
          }
      }
  
      private static void makeRefs(Object objects[], WeakReference<Object> refs[]) {
          for (int i = 0; i < objects.length; i++) {
              objects[i] = new Object();
              refs[i] = new WeakReference<Object>(objects[i]);
          }
      }
  
      private static <T> void checkRefs(T objects[], WeakReference<T> refs[]) {
          boolean ok = true;
  
          for (int i = 0; i < objects.length; i++) {
              if (refs[i].get() != objects[i]) {
                  ok = false;
              }
          }
          if (!ok) {
              throw new RuntimeException("Test failed: " +
                      "weak refs not cleared");
          }
      }
  
      @MediumTest
      public void testWeakRefs() throws Exception {
          final int NUM_REFS = 16;
  
          Object objects[] = new Object[NUM_REFS];
          WeakReference<Object> refs[] = new WeakReference[objects.length];
  
          /* Create a bunch of objects and a parallel array
          * of WeakReferences.
          */
          makeRefs(objects, refs);
          Runtime.getRuntime().gc();
          checkRefs(objects, refs);
  
          /* Clear out every other strong reference.
          */
          for (int i = 0; i < objects.length; i += 2) {
              objects[i] = null;
          }
          Runtime.getRuntime().gc();
          checkRefs(objects, refs);
  
          /* Clear out the rest of them.
          */
          for (int i = 0; i < objects.length; i++) {
              objects[i] = null;
          }
          Runtime.getRuntime().gc();
          checkRefs(objects, refs);
      }
  
      private static void makeRefs(Object objects[], PhantomReference<Object> refs[],
              ReferenceQueue<Object> queue) {
  