if (LOG.isLoggable(Level.INFO)) LOG.info("Reading HP-UX 1.4.1-1.4.2 format...");
try {
final GCModel model = new GCModel();
model.setFormat(GCModel.Format.SUN_X_LOG_GC);
String line = null;
GCEvent event = null;
while ((line = in.readLine()) != null) {
final StringTokenizer st = new StringTokenizer(line, " ");
if (st.countTokens() != 22) {
if (LOG.isLoggable(Level.WARNING)) {
LOG.warning("Malformed line (" + in.getLineNumber() + "). Wrong number of tokens ("+st.countTokens()+"): " + line);
continue;
}
}
if (!"<GC:".equals(st.nextToken())) {
if (LOG.isLoggable(Level.WARNING)) LOG.warning("Malformed line (" + in.getLineNumber() + "). Expected \"<GC:\" in " + line);
continue;
}
event = new GCEvent();
/*
%1: Indicates the type of the garbage collection.
1: represents a Scavenge (GC of New Generation only)
%2: indicates if this is a parallel scavenge.
0: non-parallel scavenge
n(>0): parallel scavenge, n represents the number of
parallel GC threads
2: represents an Old Generation GC or a Full GC
%2: indicates the GC reason:
1: Allocation failure
2: Call to System.gc
3: Tenured Generation full
4: Permanent Generation full
5: Train Generation full
6: Concurrent-Mark-Sweep (CMS) Generation full
7: Old generation expanded on last scavenge
8: Old generation too full to scavenge
9: FullGCAlot
10: Allocation profiler triggered
11: Last ditch collection
If the heap area holding the reflection objects (representing classes and methods) is
full, VM first invokes permanent generation collection. If that fails, then it tries to
expand permanent generation.
If that also fails, it invokes last ditch collection, to reclaim as much space as possible.
12: Heap dump triggered
13: gcLocker triggered
14: No cause specified
(Number 11: "Last ditch collection" is added since 1.4.2.03. Number 12, 13 and 14 are added since 1.4.2.10).
3: represents a complete background CMS GC
%2: indicates the GC reason:
1: Occupancy > initiatingOccupancy
2: Expanded recently
3: Incremental collection will fail
4: Linear allocation will fail
5: Anticipated promotion
4: represents an incomplete background CMS GC
(exited after yielding to foreground GC)
%2: n.m
n indicates the GC reason:
1: Occupancy > initiatingOccupancy
2: Expanded recently
3: Incremental collection will fail
4: Linear allocation will fail
5: Anticipated promotion
m indicates the background CMS state when yielding:
0: Resetting
1: Idling
2: InitialMarking
3: Marking
4: FinalMarking
5: Precleaning
6: Sweeping
*/
final int typeOfGC = Integer.parseInt(st.nextToken());
// %2: see above
final float gcDetails = Float.parseFloat(st.nextToken());
event.setType(findType(typeOfGC, gcDetails));
// %3: Program time at the beginning of the collection, in seconds
event.setTimestamp(NumberParser.parseDouble(st.nextToken()));
// %4: Garbage collection invocation. Counts of background CMS GCs
// and other GCs are maintained separately
st.nextToken();
// %5: Size of the object allocation request that forced the GC, in bytes
st.nextToken();
// %6: Tenuring threshold - determines how long the new born object
// remains in the New Generation
st.nextToken();
// Eden Sub-space (within the New Generation)
// %7: Before
// %8: After
// %9: Capacity
final long edenBefore = Long.parseLong(st.nextToken());
final long edenAfter = Long.parseLong(st.nextToken());
final long edenCapacity = Long.parseLong(st.nextToken());
/*
GCEvent edenEvent = new GCEvent();
edenEvent.setType(AbstractGCEvent.Type.DEF_NEW);
edenEvent.setPreUsed((int)(edenBefore / 1024));
edenEvent.setPostUsed((int)(edenAfter / 1024));
edenEvent.setTotal((int)(edenCapacity / 1024));
*/
// Survivor Sub-space (within the New Generation)
// %10: Before
// %11: After
// %12: Capacity
final long survivorBefore = Long.parseLong(st.nextToken());
final long survivorAfter = Long.parseLong(st.nextToken());
final long survivorCapacity = Long.parseLong(st.nextToken());
/*
GCEvent survivorEvent = new GCEvent();
survivorEvent.setType(AbstractGCEvent.Type.DEF_NEW);
survivorEvent.setPreUsed((int)(survivorBefore / 1024));
survivorEvent.setPostUsed((int)(survivorAfter / 1024));
survivorEvent.setTotal((int)(survivorCapacity / 1024));
*/
// Since we don't distinguish between survivor spaces and eden, we add things up.
final GCEvent newEvent = new GCEvent();
newEvent.setType(AbstractGCEvent.Type.DEF_NEW);
newEvent.setPreUsed((int)((survivorBefore + edenBefore) / 1024));
newEvent.setPostUsed((int)((survivorAfter + edenAfter) / 1024));
newEvent.setTotal((int)((survivorCapacity + edenCapacity) / 1024));
// Old Generation
// %13: Before
// %14: After
// %15: Capacity
final long oldBefore = Long.parseLong(st.nextToken());
final long oldAfter = Long.parseLong(st.nextToken());
final long oldCapacity = Long.parseLong(st.nextToken());
final GCEvent oldEvent = new GCEvent();
oldEvent.setType(AbstractGCEvent.Type.TENURED);
oldEvent.setPreUsed((int)(oldBefore / 1024));
oldEvent.setPostUsed((int)(oldAfter / 1024));
oldEvent.setTotal((int)(oldCapacity / 1024));
// Permanent Generation (Storage of Reflective Objects)
// %16: Before
// %17: After
// %18: Capacity
final long permBefore = Long.parseLong(st.nextToken());
final long permAfter = Long.parseLong(st.nextToken());
final long permCapacity = Long.parseLong(st.nextToken());
final GCEvent permEvent = new GCEvent();
permEvent.setType(AbstractGCEvent.Type.PERM);
permEvent.setPreUsed((int)(permBefore / 1024));
permEvent.setPostUsed((int)(permAfter / 1024));
permEvent.setTotal((int)(permCapacity / 1024));
// %19: The total stop-the-world duration, in seconds.
final double pause = NumberParser.parseDouble(st.nextToken());
event.setPause(pause);
// %20: The total time used in collection, in seconds.