/*
*
*
* Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 only, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is
* included at /legal/license.txt).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 or visit www.sun.com if you need additional
* information or have any questions.
*/
import java.io.*;
import java.util.*;
/**
* This program parses the event.log generated by the VM and
* calculates the extend "pause" that can be noticed by the user. The
* algorithm moves a "sliding window" across the execution history of
* a program. If the amount of "stop-the-world" activities in a
* sliding window exceeds the threshold, we discover a pause.
*
* For example, if window_size is 30 and pause_thresh is 10, and the
* first 30 ms of the execution time contains 7 msec of GC and 5 msec
* of compilation for a total of 12 ms of stop-the-world activities,
* we declare that the first sliding window contains a pause.
*/
public class ParsePauses {
/**
* The size of the sliding window, in milliseconds.
*/
static int window_size = 30;
/**
* How much stop-the-world activities can happen in a sliding window
* before we declare that the sliding window contains a pause.
*/
static int pause_thresh = 10;
static boolean verbose = false;
static class Node {
double msec;
boolean is_paused;
String type;
public String toString() {
String s1 = new PrintfFormat("%10.3f").sprintf(msec);
String s2 = new PrintfFormat("%-15s").sprintf(type);
return s1 + (is_paused ? "**" : " ") + s2;
}
}
public static void main(String args[]) throws Throwable {
try {
int n = 0;
if (args[0].equals("-v")) {
n++;
verbose = true;
}
window_size = Integer.parseInt(args[n+0]);
pause_thresh = Integer.parseInt(args[n+1]);
} catch (Throwable t) {;}
FileInputStream in = new FileInputStream("event.log");
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String s;
Vector v = new Vector();
double last_msec = 0.0;
int nestLevel = 0;
while ((s = reader.readLine()) != null) {
try {
s = s.trim();
String num = s.substring(0, s.indexOf(' '));
double d = Double.parseDouble(num);
Node n = new Node();
n.msec = d;
if (s.endsWith("END")) {
nestLevel --;
} else {
nestLevel ++;
}
n.is_paused = (nestLevel) > 0;
n.type = s.substring(s.lastIndexOf(' ')).intern();
v.addElement(n);
last_msec = d;
} catch (Throwable t) {;}
}
int total_pauses = 0;
int total_msecs = 0;
int startIdx = 0;
for (double msec = 0; msec < last_msec; msec += 1.0) {
if ((startIdx = findStartIdx(v, startIdx, msec)) < 0) {
break;
}
if (add_pauses(v, startIdx, msec)) {
total_pauses ++;
}
total_msecs ++;
}
System.out.println("pauses = " + total_pauses + "/" + total_msecs);
}
// Find the last index that precedes msec
static int findStartIdx(Vector v, int startIdx, double msec) {
boolean found = false;
for (int i=startIdx; i<v.size(); i++) {
Node n = (Node)v.elementAt(i);
if (n.msec > msec) {
if (!found) {
return startIdx;
} else {
break;
}
}
if (n.msec <= msec) {
startIdx = i;
found = true;
}
}
if (!found) {
return -1;
} else {
return startIdx;
}
}
static boolean add_pauses(Vector v, int startIdx, double begin) {
double end = begin + window_size;
for (int pass = 0; pass < 2; pass++) {
Node lastNode = null;
double total_paused = 0.0;
if (pass == 1 && verbose) {
System.out.println("========================================");
System.out.println("START" + begin);
}
for (int i=startIdx; i<v.size(); i++) {
Node n = (Node)v.elementAt(i);
if (pass == 1 && verbose) {
System.out.print(" " + n);
}
if (lastNode != null && lastNode.is_paused) {
double a = lastNode.msec;
double b = n.msec;
if (a < begin) {
a = begin;
}
if (b > end) {
b = end;
}
total_paused += (b - a);
if (pass == 1 && verbose) {
String s = new PrintfFormat("%7.3f").sprintf(b-a);
System.out.print(" += " + s);
}
}
if (pass == 1 && verbose) {
System.out.println();
}
lastNode = n;
if (n.msec >= end) {
break;
}
}
if (total_paused > pause_thresh) {
if (pass == 1) {
String s = new PrintfFormat("%.3f").sprintf(total_paused);
if (verbose) {
System.out.println();
}
System.out.println("Pause at " + begin + " ms" + " = " +
s + " ms");
return true;
}
} else {
return false;
}
}
return true;
}
}
|