/** {@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(); } } }
/** * 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; }
/** * 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); }
/** {@inheritDoc} */ protected MonitorStatus getMonitorStatus(Map<String, Monitor> map) throws MonitorException { assert Thread.holdsLock(this); assert insertedMonitors != null; // load any new monitors getNewMonitors(map); // current implementation doesn't support deletion or reuse of entries ArrayList removed = EMPTY_LIST; ArrayList inserted = insertedMonitors; insertedMonitors = new ArrayList<Monitor>(); return new MonitorStatus(inserted, removed); }
/** {@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()); }