/** * 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); } } }