Пример #1
1
  /** {@inheritDoc} */
  protected void getNewMonitors(Map<String, Monitor> map) throws MonitorException {
    assert Thread.holdsLock(this);

    int used = prologue.getUsed();
    long modificationTime = prologue.getModificationTimeStamp();

    if ((used > lastUsed) || (lastModificationTime > modificationTime)) {

      lastUsed = used;
      lastModificationTime = modificationTime;

      Monitor monitor = getNextMonitorEntry();
      while (monitor != null) {
        String name = monitor.getName();

        // guard against duplicate entries
        if (!map.containsKey(name)) {
          map.put(name, monitor);

          /*
           * insertedMonitors is null when called from pollFor()
           * via buildMonitorMap(). Since we update insertedMonitors
           * at the end of buildMonitorMap(), it's ok to skip the
           * add here.
           */
          if (insertedMonitors != null) {
            insertedMonitors.add(monitor);
          }
        }
        monitor = getNextMonitorEntry();
      }
    }
  }
Пример #2
0
  /**
   * method to make adjustments for known counter problems. This method depends on the availability
   * of certain counters, which is generally guaranteed by the synchWithTarget() method.
   */
  protected void kludge(Map<String, Monitor> map) {
    if (Boolean.getBoolean("sun.jvmstat.perfdata.disableKludge")) {
      // bypass all kludges
      return;
    }

    String name = "java.vm.version";
    StringMonitor jvm_version = (StringMonitor) map.get(name);
    if (jvm_version == null) {
      jvm_version = (StringMonitor) findByAlias(name);
    }

    name = "java.vm.name";
    StringMonitor jvm_name = (StringMonitor) map.get(name);
    if (jvm_name == null) {
      jvm_name = (StringMonitor) findByAlias(name);
    }

    name = "hotspot.vm.args";
    StringMonitor args = (StringMonitor) map.get(name);
    if (args == null) {
      args = (StringMonitor) findByAlias(name);
    }

    assert ((jvm_name != null) && (jvm_version != null) && (args != null));

    if (jvm_name.stringValue().indexOf("HotSpot") >= 0) {
      if (jvm_version.stringValue().startsWith("1.4.2")) {
        kludgeMantis(map, args);
      }
    }
  }
Пример #3
0
  /** Method to dump debugging information */
  private void dumpAll(Map map, int lvmid) {
    if (DEBUG) {
      Set keys = map.keySet();

      System.err.println("Dump for " + lvmid);
      int j = 0;
      for (Iterator i = keys.iterator(); i.hasNext(); j++) {
        Monitor monitor = (Monitor) map.get(i.next());
        System.err.println(j + "\t" + monitor.getName() + "=" + monitor.getValue());
      }
      System.err.println("nextEntry = " + nextEntry + " pollForEntry = " + pollForEntry);
      System.err.println("Buffer info:");
      System.err.println("buffer = " + buffer);
    }
  }
Пример #4
0
  /**
   * Method to poll the instrumentation memory for a counter with the given name. The polling period
   * is bounded by the timeLimit argument.
   */
  protected Monitor pollFor(Map<String, Monitor> map, String name, long timeLimit)
      throws MonitorException {
    Monitor monitor = null;

    log("polling for: " + lvmid + "," + name + " ");

    pollForEntry = nextEntry;
    while ((monitor = map.get(name)) == null) {
      log(".");

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

      long t = System.currentTimeMillis();
      if ((t > timeLimit) || (overflow.intValue() > 0)) {
        lognl("failed: " + lvmid + "," + name);
        dumpAll(map, lvmid);
        throw new MonitorException("Could not find expected counter");
      }

      getNewMonitors(map);
    }
    lognl("success: " + lvmid + "," + name);
    return monitor;
  }
Пример #5
0
  /** {@inheritDoc} */
  protected void buildMonitorMap(Map<String, Monitor> map) throws MonitorException {
    assert Thread.holdsLock(this);

    // start at the beginning of the buffer
    buffer.rewind();

    // create pseudo monitors
    buildPseudoMonitors(map);

    // position buffer to start of the data section
    buffer.position(prologue.getSize());
    nextEntry = buffer.position();
    perfDataItem = 0;

    int used = prologue.getUsed();
    long modificationTime = prologue.getModificationTimeStamp();

    Monitor m = getNextMonitorEntry();
    while (m != null) {
      map.put(m.getName(), m);
      m = getNextMonitorEntry();
    }

    /*
     * set the last modification data. These are set to the values
     * recorded before parsing the data structure. This allows the
     * the data structure to be modified while the Map is being built.
     * The Map may contain more entries than indicated based on the
     * time stamp, but this is handled by ignoring duplicate entries
     * when the Map is updated in getNewMonitors().
     */
    lastUsed = used;
    lastModificationTime = modificationTime;

    // synchronize with the target jvm
    synchWithTarget(map);

    // work around 1.4.2 counter inititization bugs
    kludge(map);

    insertedMonitors = new ArrayList<Monitor>(map.values());
  }
Пример #6
0
  /** Build the pseudo monitors used to map the prolog data into counters. */
  protected void buildPseudoMonitors(Map<String, Monitor> map) {
    Monitor monitor = null;
    String name = null;
    IntBuffer ib = null;

    name = PerfDataBufferPrologue.PERFDATA_MAJOR_NAME;
    ib = prologue.majorVersionBuffer();
    monitor = new PerfIntegerMonitor(name, Units.NONE, Variability.CONSTANT, false, ib);
    map.put(name, monitor);

    name = PerfDataBufferPrologue.PERFDATA_MINOR_NAME;
    ib = prologue.minorVersionBuffer();
    monitor = new PerfIntegerMonitor(name, Units.NONE, Variability.CONSTANT, false, ib);
    map.put(name, monitor);

    name = PerfDataBufferPrologue.PERFDATA_BUFFER_SIZE_NAME;
    ib = prologue.sizeBuffer();
    monitor = new PerfIntegerMonitor(name, Units.BYTES, Variability.MONOTONIC, false, ib);
    map.put(name, monitor);

    name = PerfDataBufferPrologue.PERFDATA_BUFFER_USED_NAME;
    ib = prologue.usedBuffer();
    monitor = new PerfIntegerMonitor(name, Units.BYTES, Variability.MONOTONIC, false, ib);
    map.put(name, monitor);

    name = PerfDataBufferPrologue.PERFDATA_OVERFLOW_NAME;
    ib = prologue.overflowBuffer();
    monitor = new PerfIntegerMonitor(name, Units.BYTES, Variability.MONOTONIC, false, ib);
    map.put(name, monitor);
    this.overflow = (IntegerMonitor) monitor;

    name = PerfDataBufferPrologue.PERFDATA_MODTIMESTAMP_NAME;
    LongBuffer lb = prologue.modificationTimeStampBuffer();
    monitor = new PerfLongMonitor(name, Units.TICKS, Variability.MONOTONIC, false, lb);
    map.put(name, monitor);
  }
Пример #7
0
  /**
   * 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);
      }
    }
  }