/**
   * Method to provide a gross level of synchronization with the target monitored jvm.
   *
   * <p>gross synchronization works by polling for the hotspot.rt.hrt.ticks counter, which is the
   * last counter created by the StatSampler initialization code. The counter is updated when the
   * watcher thread starts scheduling tasks, which is the last thing done in vm initialization.
   */
  protected void synchWithTarget(Map<String, Monitor> map) throws MonitorException {
    /*
     * synch must happen with syncWaitMs from now. Default is 5 seconds,
     * which is reasonabally generous and should provide for extreme
     * situations like startup delays due to allocation of large ISM heaps.
     */
    long timeLimit = System.currentTimeMillis() + syncWaitMs;

    String name = "hotspot.rt.hrt.ticks";
    LongMonitor ticks = (LongMonitor) pollFor(map, name, timeLimit);

    /*
     * loop waiting for the ticks counter to be non zero. This is
     * an indication that the jvm is initialized.
     */
    log("synchWithTarget: " + lvmid + " ");
    while (ticks.longValue() == 0) {
      log(".");

      try {
        Thread.sleep(20);
      } catch (InterruptedException e) {
      }

      if (System.currentTimeMillis() > timeLimit) {
        lognl("failed: " + lvmid);
        throw new MonitorException("Could Not Synchronize with target");
      }
    }
    lognl("success: " + lvmid);
  }
  /**
   * method to repair the 1.4.2 parallel scavenge counters that are incorrectly initialized by the
   * JVM when UseAdaptiveSizePolicy is set. This bug couldn't be fixed for 1.4.2 FCS due to putback
   * restrictions.
   */
  private void kludgeMantis(Map<String, Monitor> map, StringMonitor args) {
    /*
     * the HotSpot 1.4.2 JVM with the +UseParallelGC option along
     * with its default +UseAdaptiveSizePolicy option has a bug with
     * the initialization of the sizes of the eden and survivor spaces.
     * See bugid 4890736.
     *
     * note - use explicit 1.4.2 counter names here - don't update
     * to latest counter names or attempt to find aliases.
     */

    String cname = "hotspot.gc.collector.0.name";
    StringMonitor collector = (StringMonitor) map.get(cname);

    if (collector.stringValue().compareTo("PSScavenge") == 0) {
      boolean adaptiveSizePolicy = true;

      /*
       * HotSpot processes the -XX:Flags/.hotspotrc arguments prior to
       * processing the command line arguments. This allows the command
       * line arguments to override any defaults set in .hotspotrc
       */
      cname = "hotspot.vm.flags";
      StringMonitor flags = (StringMonitor) map.get(cname);
      String allArgs = flags.stringValue() + " " + args.stringValue();

      /*
       * ignore the -XX: prefix as it only applies to the arguments
       * passed from the command line (i.e. the invocation api).
       * arguments passed through .hotspotrc omit the -XX: prefix.
       */
      int ahi = allArgs.lastIndexOf("+AggressiveHeap");
      int aspi = allArgs.lastIndexOf("-UseAdaptiveSizePolicy");

      if (ahi != -1) {
        /*
         * +AggressiveHeap was set, check if -UseAdaptiveSizePolicy
         * is set after +AggressiveHeap.
         */
        //
        if ((aspi != -1) && (aspi > ahi)) {
          adaptiveSizePolicy = false;
        }
      } else {
        /*
         * +AggressiveHeap not set, must be +UseParallelGC. The
         * relative position of -UseAdaptiveSizePolicy is not
         * important in this case, as it will override the
         * UseParallelGC default (+UseAdaptiveSizePolicy) if it
         * appears anywhere in the JVM arguments.
         */
        if (aspi != -1) {
          adaptiveSizePolicy = false;
        }
      }

      if (adaptiveSizePolicy) {
        // adjust the buggy AdaptiveSizePolicy size counters.

        // first remove the real counters.
        String eden_size = "hotspot.gc.generation.0.space.0.size";
        String s0_size = "hotspot.gc.generation.0.space.1.size";
        String s1_size = "hotspot.gc.generation.0.space.2.size";
        map.remove(eden_size);
        map.remove(s0_size);
        map.remove(s1_size);

        // get the maximum new generation size
        String new_max_name = "hotspot.gc.generation.0.capacity.max";
        LongMonitor new_max = (LongMonitor) map.get(new_max_name);

        /*
         * replace the real counters with pseudo counters that are
         * initialized to to the correct values. The maximum size of
         * the eden and survivor spaces are supposed to be:
         *    max_eden_size = new_size - (2*alignment).
         *    max_survivor_size = new_size - (2*alignment).
         * since we don't know the alignment value used, and because
         * of other parallel scavenge bugs that result in oversized
         * spaces, we just set the maximum size of each space to the
         * full new gen size.
         */
        Monitor monitor = null;

        LongBuffer lb = LongBuffer.allocate(1);
        lb.put(new_max.longValue());
        monitor = new PerfLongMonitor(eden_size, Units.BYTES, Variability.CONSTANT, false, lb);
        map.put(eden_size, monitor);

        monitor = new PerfLongMonitor(s0_size, Units.BYTES, Variability.CONSTANT, false, lb);
        map.put(s0_size, monitor);

        monitor = new PerfLongMonitor(s1_size, Units.BYTES, Variability.CONSTANT, false, lb);
        map.put(s1_size, monitor);
      }
    }
  }