Express (Distributed operating systems), v8.0 > Troubleshoot and support > Analyzing application server Java system dumps with the IBM Monitoring and Diagnostic Tools for Java - Dump Analyzer > Write a new analysis module or script > Write and running a new analysis module


An example of a more complex analyzer

The code in List 3 demonstrates a class that implements both the IAnalyze and the IReport interfaces. This slightly more complex example provides both analysis and reporting capability which is intended to examine the object population in the VM. When doing analysis it outputs some counts of the number of heaps, number of objects and number of arrays. We then implement some simple rules which would allow a script to categorize the dump in some way, in this example we have implemented two rules;'bad data' and 'many objects'.

List 3. Example of an Analyzer that implements both IAnalyze and IReport

 package com.ibm.dtfj.analyzer;

import java.util.Iterator;

import com.ibm.dtfj.analyzer.base.AnalyzerBase;
import com.ibm.dtfj.analyzer.ext.IAnalysisReport;
import com.ibm.dtfj.analyzer.ext.IAnalyze;
import com.ibm.dtfj.analyzer.ext.IReport;
import com.ibm.dtfj.analyzer.util.DTFJIterator;
import com.ibm.dtfj.java.JavaHeap;
import com.ibm.dtfj.java.JavaObject;
import com.ibm.dtfj.java.JavaRuntime;

/**
 * This analyzer will examine all the heaps and work out the object populations.
 */
public class SummariseHeaps extends AnalyzerBase implements IAnalyze, IReport {
 private static String description = "Show the object populations";
 private int corruptObjects;
 private int nHeaps;
 private int nObjects;
 private int nArrays;
 private int nObjectBytes;
 private int nArrayBytes;

 private static String[] dataCheck = {
  "corruptData  >  0 ERROR",  // any corruptions are bad
  "otherErrors    >  0 ERROR"   // any other errors are also bad
 };
 private static String[] manyObjects = {
  "nObjects
      > 10000 TRUE",  // define a rule to be true if the number of objects or arrays exceeds 10000
  "nArrays
       > 10000 TRUE"
 };
 public Sample3() {
  defineRule("bad data",dataCheck);
  defineRule("many objects",manyObjects);
 }
 public String getShortDescription() {
  return description;
 }
 public String[] doAnalysis() {
  String[] ret = new String[7];
  analyzeHeap(getContext().getCurrentJavaRuntime(),null);
  ret[0] = "corruptData="     + getTotalCorruptDataErrors();
  ret[1] = "unavailableData=" + getTotalDataUnavailable();
  ret[2] = "otherErrors="  + getTotalOtherErrors();
  ret[3] = "countHeaps="   + nHeaps;
  ret[3] = "countObjects=" + nObjects;
  ret[4] = "countArrays="  + nArrays;
  ret[5] = "objectBytes="  + nObjectBytes;
  ret[6] = "arrayBytes="   + nArrayBytes;
  return ret;
 }
 public IAnalysisReport produceReport() {
  IAnalysisReport ret = allocateReport();
  analyzeHeap(getContext().getCurrentJavaRuntime(),ret); // get the JavaRuntime
  return ret;
 }
 private void analyzeHeap(JavaRuntime r, IAnalysisReport report) {
  try {
   Iterator it = buildSafeIterator(r.getHeaps()); // avoid CorruptData
   while (it.hasNext()) {
    JavaHeap heap = (JavaHeap)it.next();
    showJavaHeap(heap,report);
    nHeaps++;
   }
  } catch (Exception e) {
   // this inherited method keeps track of missing and corrupt data exceptions
   handleError("Failed to get heap information",e);
  }
 }
 private void showJavaHeap(JavaHeap heap, IAnalysisReport report) {
  try {
   int nObj
     = 0;
   int nArr
     = 0;
   int nObjBytes = 0;
   int nArrBytes = 0;
   DTFJIterator it = buildSafeIterator(heap.getObjects());
   while (it.hasNext()) {
    JavaObject obj = (JavaObject)it.next();
    long bytes = obj.getSize();
    if (obj.isArray()) {
     nArr++;
     nArrBytes += bytes;
    } else {
     nObj++;
     nObjBytes += bytes;
    }
   }
   nObjects
    += nObj;
   nObjectBytes += nObjBytes;
   nArrays
     += nArr;
   nArrayBytes  += nArrBytes;
   if (report != null) {
    report.startSection("Heap " + heap.getName());
    report.printField("Total objects"     ,nObj);
    report.printField("Total object bytes",nObjBytes);
    report.printField("Total arrays"      ,nArrays);
    report.printField("Total array bytes ",nArrBytes);
    report.printField("Total corrupt objects",it.getCorruptObjectCount());
    report.endSection();
   }
  } catch (Exception e) {
   handleError("Failed to get heap objects",e);
  }
 }
}

We have introduced a number of new concepts with this example. In addition to the basics of implementing the required interfaces we have made use of various facilities for navigating the objects within the dump. Initially we obtained the current Runtime object and from it we obtained an Iterator over all the Heaps in the dump. To save us having to deal with the complexities of missing or corrupt data we then wrapped that with a DTFJIterator which hides these exceptional conditions and allows us to count them separately. We then do the same trick to get hold of an iterator on the objects within the heap. The other concept that we have introduced is the report formatting. By adding fields to the report we allow the DumpAnalyzer to format the result in a variety of ways; raw text, html, xml etc. disclosure restricted by GSA ADP Schedule Contract with IBM Corp.

+

Search Tips   |   Advanced Search