[jboss-cvs] jboss-profiler/docbook/en/modules ...

Clebert Suconic csuconic at jboss.com
Fri Nov 10 12:40:20 EST 2006


  User: csuconic
  Date: 06/11/10 12:40:20

  Added:       docbook/en/modules       runtime.xml webinterface.xml
                        concept.xml memory.xml jvmti.xml compiling.xml
  Log:
  Adding docbook under jboss-profiler tree
  
  Revision  Changes    Path
  1.1      date: 2006/11/10 17:40:20;  author: csuconic;  state: Exp;jboss-profiler/docbook/en/modules/runtime.xml
  
  Index: runtime.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <chapter id="runtime">
    <title>Runtime Profiler</title>
  
    <sect1 id="conceptrun">
      <title>Events covered during runtime analysis</title>
  
      <para>When using the Runtime Profiler, you are interested in the behavior
      of your methods during execution.</para>
  
      <para>We extract information about method calls showing % information
      relative to CPU and elapsed time. We also show information about memory
      consumption from these methods.</para>
  
      <para>Say, if a method allocates an object, you will have an enter-method
      event, and a objectalloc during its execution.</para>
  
      <para>Later on, when you have a GC operation we will have release objects
      events. As we identified the object during its creation we can determine
      where the object was created, so we can show if a method is generating
      leaks or not.</para>
    </sect1>
  
    <sect1 id="log">
      <title>Capturing Log Files</title>
  
      <para>The interceptor stays sleeping, not consuming any resources from the
      JVM until it receives a weak-up method.</para>
  
      <para>This is done by the MBean at the WebConsole. (e.g.
      http://localhost:8080/jmx-console).</para>
  
      <para>You have to look for the bean mbean=Native-profiler</para>
  
      <para>After you have selected the MBean you will be able to:</para>
  
      <para><itemizedlist>
          <listitem>
            <para>pause - Temporarily stops data collection</para>
          </listitem>
  
          <listitem>
            <para>stop - Definitely close all the files</para>
  
            <para>After this point, you can't collect more data and you need to
            restart your application server if you want to collect more.</para>
  
            <para>After this point also, the application keeps running.</para>
          </listitem>
  
          <listitem>
            <para>activate - Start/Resume capturing data</para>
          </listitem>
        </itemizedlist></para>
  
      <figure>
        <title></title>
  
        <screenshot>
          <screeninfo></screeninfo>
  
          <mediaobject>
            <imageobject>
              <imagedata align="center" fileref="images/Screenshot-MBean.png" />
            </imageobject>
          </mediaobject>
        </screenshot>
      </figure>
    </sect1>
  
    <sect1>
      <title>Installing the MBean</title>
  
      <para>To install the Native MBean you need to copy
      jboss-profiler-noAOP.sar into your /server/deploy directory</para>
    </sect1>
  
    <sect1>
      <title>Installing the Native Library (DLL/SO)</title>
  
      <para>The only thing needed to have access to the native library, is to
      have defined LD_LIBRARY_PATH (if Linux) or under the PATH (for
      Windows).</para>
  
      <para>Although sometimes is hard to distribute native code under Linux. On
      that case you would have to recompile the native code in your
      library.</para>
  
      <para>You can test if the installation works by doing a simple:</para>
  
      <para><literallayout>java -XrunjbossInspector:/tmp Foo
  
  If the only error message you get is Class Foo not found, your native library installation is working</literallayout></para>
  
      <sect2>
        <title>Compiling the Native Library</title>
  
        <para>You have of course to download the source code from CVS
        first.</para>
  
        <para>After you have download it, you need to:</para>
  
        <itemizedlist>
          <listitem>
            <para>Make sure you gnu/gcc works</para>
          </listitem>
  
          <listitem>
            <para>Define JAVA_HOME to a JDK as we need access to some
            includes</para>
          </listitem>
  
          <listitem>
            <para>Under &lt;jboss-profiler-src&gt;/native/&lt;platform&gt;,
            execute the compilation script</para>
          </listitem>
        </itemizedlist>
      </sect2>
    </sect1>
  
    <sect1>
      <title>Start/Stop/Pause using the API</title>
  
      <para>It is possible to directly use a
      org.jboss.profiler.threadcheck.StartupProfilerCheck to control the life
      cycle of your profiling.</para>
  
      <para>StartupProfilerCheck is defined at profilerConsole.jar. You have
      three methods defined:</para>
  
      <para><literallayout>   private native static void startProfilerInternal();
     private native static void pauseProfilerInternal();
     private native static void stopProfilerInternal();
  </literallayout></para>
  
      <para>These three methods are defined at jbossInspector.dll (or .so for
      Solaris or .jnilib for apple)</para>
    </sect1>
  </chapter>
  
  
  1.1      date: 2006/11/10 17:40:20;  author: csuconic;  state: Exp;jboss-profiler/docbook/en/modules/webinterface.xml
  
  Index: webinterface.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <chapter id="webinterface">
    <title>Webinterface</title>
  
    <sect1 id="webinterface-runtime">
      <title>Runtime Profiler</title>
  
      <sect2>
        <title>Running Application</title>
  
        <para>To start analyzing after the deployment, open this URL into your
        WEB-Browser.</para>
  
        <para><link
        linkend="???">http://localhost:8080/jboss-profiler</link></para>
  
        <figure>
          <title></title>
  
          <screenshot>
            <screeninfo></screeninfo>
  
            <mediaobject>
              <imageobject>
                <imagedata align="center"
                           fileref="images/Screenshot-Runtime.png" />
              </imageobject>
            </mediaobject>
          </screenshot>
        </figure>
  
        <para>You will have to type the directory where you added the log files.
        It was not possible to create a select button as this is a Web
        application. The good thing about a WebApplication for a profiler, is
        that you can have people analyzing data remotely. (This is a good tool
        for consultants. support staff and architects that may not be on
        site)</para>
      </sect2>
  
      <sect2>
        <title>Selecting the Process ID</title>
  
        <figure>
          <title></title>
  
          <screenshot>
            <screeninfo></screeninfo>
  
            <mediaobject>
              <imageobject>
                <imagedata align="center" fileref="images/Screenshot-PID.png" />
              </imageobject>
            </mediaobject>
          </screenshot>
        </figure>
  
        <para>Besides the option to select any process id you might need, you
        have also three extra options that will control how to analyze the
        log-files into profiler’s object-model:</para>
  
        <para><itemizedlist>
            <listitem>
              <para>Stack on objects</para>
  
              <para>You can locate where objects are created if this feature is
              enabled</para>
            </listitem>
  
            <listitem>
              <para>Stack on methods</para>
  
              <para>You can generate the iteration between methods callings. If
              not activated you won’t have reference information between
              methods.</para>
            </listitem>
          </itemizedlist><itemizedlist>
            <listitem>
              <para>Calculate releases on GC operations</para>
  
              <para>If activated a complete reference between object ids and
              methods ID. It’s a good option to locate memory-leaks</para>
            </listitem>
          </itemizedlist></para>
  
        <para>After submit this following processing screen will be
        viewed.</para>
  
        <figure>
          <title></title>
  
          <screenshot>
            <screeninfo></screeninfo>
  
            <mediaobject>
              <imageobject>
                <imagedata align="center"
                           fileref="images/Screenshot-Servlet.png" />
              </imageobject>
            </mediaobject>
          </screenshot>
        </figure>
  
        <para>Follow the link, and you will see Process-View/Methods view as
        default: You can have this view by clicking on
        ProcessView-methods.</para>
  
        <figure>
          <title></title>
  
          <screenshot>
            <screeninfo></screeninfo>
  
            <mediaobject>
              <imageobject>
                <imagedata align="center"
                           fileref="images/Screenshot-ProceessView_Methods-tracing.png" />
              </imageobject>
            </mediaobject>
          </screenshot>
        </figure>
  
        <para>You can proceed from this view to each of steps described in the
        following sections respectively.</para>
      </sect2>
  
      <sect2>
        <title>Detailing method’s execution</title>
  
        <para>You can click on the arrow icon to detail method’s execution: You
        can repeat that operation as many times you want inside method’s
        execution. Clicking on method’s name (a hyperlink) has the same
        effect.</para>
  
        <figure>
          <title></title>
  
          <screenshot>
            <screeninfo></screeninfo>
  
            <mediaobject>
              <imageobject>
                <imagedata align="center"
                           fileref="images/Screenshot-MethodsDetail.png" />
              </imageobject>
            </mediaobject>
          </screenshot>
        </figure>
  
        <para>After you got on methods detail, you can have four views about the
        current graph:</para>
  
        <itemizedlist>
          <listitem>
            <para>Critical Path</para>
          </listitem>
        </itemizedlist>
  
        <figure>
          <title></title>
  
          <screenshot>
            <screeninfo></screeninfo>
  
            <mediaobject>
              <imageobject>
                <imagedata align="center"
                           fileref="images/Screenshot-CriticalPath.png" />
              </imageobject>
            </mediaobject>
          </screenshot>
        </figure>
  
        <itemizedlist>
          <listitem>
            <para>Pie Chart</para>
          </listitem>
        </itemizedlist>
  
        <figure>
          <title></title>
  
          <screenshot>
            <screeninfo></screeninfo>
  
            <mediaobject>
              <imageobject>
                <imagedata align="center"
                           fileref="images/Screenshot-PieChart.png" />
              </imageobject>
            </mediaobject>
          </screenshot>
        </figure>
  
        <itemizedlist>
          <listitem>
            <para>Instances Created:</para>
  
            <para>(There is an extra view that adds sub-methods events)</para>
  
            <figure>
              <title></title>
  
              <screenshot>
                <screeninfo></screeninfo>
  
                <mediaobject>
                  <imageobject>
                    <imagedata align="center"
                               fileref="images/Screenshot-InstancesCreated.png" />
                  </imageobject>
                </mediaobject>
              </screenshot>
            </figure>
  
            <para>On this view you have information about how many objects were
            created and <emphasis role="bold">released</emphasis> on that slice
            of the graph. You have a <emphasis role="bold">complete</emphasis>
            information about memory-leaks.</para>
          </listitem>
        </itemizedlist>
  
        <itemizedlist>
          <listitem>
            <para>Memory operations (ProcessView-&gt;Memory)</para>
  
            <para>On Process-View/Memory you can look at GC operations:</para>
  
            <figure>
              <title></title>
  
              <screenshot>
                <screeninfo></screeninfo>
  
                <mediaobject>
                  <imageobject>
                    <imagedata align="center"
                               fileref="images/Screenshot-ProcessView_Memory.png" />
                  </imageobject>
                </mediaobject>
              </screenshot>
            </figure>
  
            <para>You can detail a GC operation:</para>
  
            <para>Byou</para>
  
            <figure>
              <title></title>
  
              <screenshot>
                <screeninfo></screeninfo>
  
                <mediaobject>
                  <imageobject>
                    <imagedata align="center"
                               fileref="images/Screenshot-GcDetail.png" />
                  </imageobject>
                </mediaobject>
              </screenshot>
            </figure>
  
            <para>You can look for Leaks, have information about Creations or
            Threads on this view.</para>
          </listitem>
        </itemizedlist>
  
        <itemizedlist>
          <listitem>
            <para>Consolidated View</para>
  
            <figure>
              <title></title>
  
              <screenshot>
                <screeninfo></screeninfo>
  
                <mediaobject>
                  <imageobject>
                    <imagedata align="center"
                               fileref="images/Screenshot-ConsolidatedView.png" />
                  </imageobject>
                </mediaobject>
              </screenshot>
            </figure>
  
            <para>On consolidated view, after you set filter parameters, you can
            generate a XML, XLS or zipped XML about the model:</para>
          </listitem>
        </itemizedlist>
  
        <figure>
          <title></title>
  
          <screenshot>
            <screeninfo></screeninfo>
  
            <mediaobject>
              <imageobject>
                <imagedata align="center" fileref="images/Screenshot-XML.png" />
              </imageobject>
            </mediaobject>
          </screenshot>
        </figure>
      </sect2>
  
      <sect2>
        <title>Tracing</title>
  
        <para>You can click on the "Tracing" field to detail the flow of
        "transaction" which is a sequence of methods executed in each method,
        and this following processing screen will be viewed.</para>
  
        <figure>
          <title></title>
  
          <screenshot>
            <screeninfo></screeninfo>
  
            <mediaobject>
              <imageobject>
                <imagedata align="center"
                           fileref="images/Screenshot-Tracing_Servlet.png" />
              </imageobject>
            </mediaobject>
          </screenshot>
        </figure>
  
        <para>Follow the link, and you will see the following view.</para>
  
        <figure>
          <title></title>
  
          <screenshot>
            <screeninfo></screeninfo>
  
            <mediaobject>
              <imageobject>
                <imagedata align="center"
                           fileref="images/Screenshot-Tracing_View.png" />
              </imageobject>
            </mediaobject>
          </screenshot>
        </figure>
  
        <para>The upper part (list view) of the view lists all transactions of
        the clicked method. The lower part (search view) provides an interface
        where you can set conditions for searching specific transactions. The
        "search view" lists the following items.</para>
  
        <itemizedlist>
          <listitem>
            <para>start method name</para>
  
            <para>Name of the clicked method.</para>
          </listitem>
        </itemizedlist>
  
        <itemizedlist>
          <listitem>
            <para>transaction type</para>
  
            <para>You can specify whether target transactions are complete or
            not. "Transaction type" has 3 choices.</para>
  
            <itemizedlist>
              <listitem>
                <para>complete</para>
  
                <para>This choice picks up transactions which have completed
                from start to finish.</para>
              </listitem>
  
              <listitem>
                <para>incomplete</para>
  
                <para>This choice picks up transactions which have aborted
                halfway.</para>
              </listitem>
  
              <listitem>
                <para>both</para>
  
                <para>This choice picks up both "complete" and "incomplete"
                transactions. (default)</para>
              </listitem>
            </itemizedlist>
          </listitem>
        </itemizedlist>
  
        <itemizedlist>
          <listitem>
            <para>search conditions</para>
  
            <para>For setting conditions, you have 6 options. If you select more
            than 1 option, target transactions will have to meet conditions of
            all the selected options. "Search conditions" has 6 choices.</para>
  
            <itemizedlist>
              <listitem>
                <para>Period where target transactions have started</para>
  
                <para>Specify start time and finish time of the period as
                follows.</para>
  
                <para><emphasis role="bold">MM/dd/yyyy
                hh:mm:ss:SSS</emphasis></para>
              </listitem>
  
              <listitem>
                <para>Period where target transactions have finished</para>
  
                <para>Specify start time and finish time of the period as
                follows.</para>
  
                <para><emphasis role="bold">MM/dd/yyyy
                hh:mm:ss:SSS</emphasis></para>
              </listitem>
  
              <listitem>
                <para>Any method(s) executed in target transactions</para>
  
                <para>Specify any string which is a part of the method's name.
                You can specify more than one string by separating them by
                space(" "). If you do so, the tracer picks up transactions
                executing all of them (AND condition), or transactions executing
                at least one of them (OR condition).</para>
              </listitem>
  
              <listitem>
                <para>Any method(s) <emphasis role="bold">not</emphasis>
                executed in target transactions</para>
  
                <para>Specify any string which is a part of the method's name.
                You can specify more than one string by separating them by
                space(" "). If you do so, the tracer picks up transactions not
                executing any of them (NOR condition), or transactions not
                executing all of them (NAND condition).</para>
              </listitem>
  
              <listitem>
                <para>Duration of target transactions</para>
  
                <para>Specify duration by millisecond (SSS), and the tracer
                picks up transactions elapsing more than the duration.</para>
              </listitem>
  
              <listitem>
                <para>Duration of any method executed in target
                transactions</para>
  
                <para>Specify duration by millisecond (SSS), and the tracer
                picks up transactions including any method(s) elapsing more than
                the duration.</para>
              </listitem>
            </itemizedlist>
          </listitem>
        </itemizedlist>
  
        <para>Set conditions as you like and submit, and the tracer picks up
        transactions meeting the conditions. The "list view" will be refreshed
        to list them. The table has the following fields.</para>
  
        <itemizedlist>
          <listitem>
            <para>Start Time</para>
  
            <para>Start time of the transaction.</para>
          </listitem>
        </itemizedlist>
  
        <itemizedlist>
          <listitem>
            <para>End Time</para>
  
            <para>Finish Time of the transaction.</para>
          </listitem>
        </itemizedlist>
  
        <itemizedlist>
          <listitem>
            <para>Total Time</para>
  
            <para>Duration of the transaction by the millisecond.</para>
          </listitem>
        </itemizedlist>
  
        <itemizedlist>
          <listitem>
            <para>#Methods</para>
  
            <para>The number of methods executed in the transaction.</para>
          </listitem>
        </itemizedlist>
  
        <itemizedlist>
          <listitem>
            <para>CPU</para>
  
            <para>CPU usage time of the transaction in nanosecond.</para>
          </listitem>
        </itemizedlist>
  
        <itemizedlist>
          <listitem>
            <para>#Locks</para>
  
            <para>The number of locks in the transaction if any. If not, this
            field is empty.</para>
          </listitem>
        </itemizedlist>
  
        <itemizedlist>
          <listitem>
            <para>Lock Time</para>
  
            <para>Duration of the locks in the transaction in millisecond. If
            there is are no locks, this field is empty.</para>
          </listitem>
        </itemizedlist>
  
        <para>You can click on the arrow icon to detail each transaction. You
        will see "transaction details view".</para>
  
        <figure>
          <title></title>
  
          <screenshot>
            <screeninfo></screeninfo>
  
            <mediaobject>
              <imageobject>
                <imagedata align="center"
                           fileref="images/Screenshot-Tracing_Detail.png" />
              </imageobject>
            </mediaobject>
          </screenshot>
        </figure>
  
        <para>The table has the following fields.</para>
  
        <itemizedlist>
          <listitem>
            <para>Methods Order</para>
  
            <para>Methods executed in the transaction are listed in sequence.
            Indented methods mean nests. If you have specified any executed
            method(s) on "search view" mentioned above, it/they is/are drawn in
            different color from other methods.</para>
          </listitem>
        </itemizedlist>
  
        <itemizedlist>
          <listitem>
            <para>Start Time</para>
  
            <para>Start time of each method.</para>
          </listitem>
        </itemizedlist>
  
        <itemizedlist>
          <listitem>
            <para>End Time</para>
  
            <para>Finish time of each method. If you have chose "both" or
            "incomplete" of "transaction type" item on "search view", this field
            says "NOT EXIT" for any incomplete methods.</para>
          </listitem>
        </itemizedlist>
  
        <itemizedlist>
          <listitem>
            <para>Total Time</para>
  
            <para>Duration of each method by the millisecond. If you have chose
            "both" or "incomplete" of "transaction type" item on "search view",
            this field says "UNKNOWN" for any incomplete methods.</para>
          </listitem>
        </itemizedlist>
  
        <itemizedlist>
          <listitem>
            <para>CPU Time</para>
  
            <para>CPU usage time of each method.</para>
          </listitem>
        </itemizedlist>
  
        <itemizedlist>
          <listitem>
            <para>#Locks</para>
  
            <para>The number of locks in each method if any. If not, this field
            is empty.</para>
          </listitem>
        </itemizedlist>
  
        <itemizedlist>
          <listitem>
            <para>Lock Time</para>
  
            <para>Duration of the locks in each method in millisecond. If there
            is are no locks, this field is empty.</para>
          </listitem>
        </itemizedlist>
      </sect2>
    </sect1>
  
    <sect1 id="webinterface-memory">
      <title>Memory Profiler</title>
  
      <para></para>
    </sect1>
  </chapter>
  
  
  1.1      date: 2006/11/10 17:40:20;  author: csuconic;  state: Exp;jboss-profiler/docbook/en/modules/concept.xml
  
  Index: concept.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <chapter id="concept">
    <title>Concept</title>
  
    <sect1 id="Interceptors">
      <title>How it Works</title>
  
      <para>The idea is simple, an interceptor sends events to a LOG file.
      Another application (WEB application) reads its contents and shows
      analysis.</para>
  
      <para>Most of the work is done by the Analysis tool, and that's a good
      thing as the work of analyzing the application is done outside of the
      JVM's runtime. What I have seen from users is that this increases the
      possibility of analysis and the user ends up capturing more
      information.</para>
  
      <para>Also, the idea of the interceptor is to stay "sleeping" until
      someone wakes him up. This is always done by MBeans and there is a MBean
      that manages each interceptor.</para>
  
      <figure id="how-it-works.fig">
        <title>Flow of Log Files</title>
  
        <mediaobject>
          <imageobject>
            <imagedata align="center" fileref="images/HowItWorks.jpg" />
          </imageobject>
        </mediaobject>
      </figure>
    </sect1>
  
    <sect1 id="JVMPI">
      <title>JVMPI - Java Virtual Machine Profiler Interface</title>
  
      <para>JVMPI is the interface defined for profiler events until JVM 1.4.
      It's still supported in JVM 1.5, but will be removed soon. JVMPI is an
      experimental C interface where you can capture events like enter method,
      exit method, class-loading.</para>
  
      <para>When the interceptor is active, these events are saved in binary
      files for later processing:</para>
  
      <itemizedlist>
        <listitem>
          <para>ClassLoad</para>
        </listitem>
  
        <listitem>
          <para>Enter Method / Enter Exit</para>
        </listitem>
  
        <listitem>
          <para>Object Alloc/Object Release</para>
        </listitem>
  
        <listitem>
          <para>GCStart/GCFinish</para>
        </listitem>
      </itemizedlist>
  
      <sect2>
        <title>Options</title>
  
        <para><itemizedlist>
            <listitem>
              <para>Add the
              -XrunjbossInspector:&lt;directory&gt;,&lt;options...&gt; as a
              parameter to your JVM. (Sun's or IBM's JVM)</para>
  
              <literallayout>Possible options include:
      start=&lt;prefix name&gt;
      include=&lt;prefix name&gt;
      ignore=&lt;prefix name&gt;
      socket=&lt;server|IP&gt;:&lt;port&gt;
      uniqueNames=true
      wakeupOnStartup=true
          Start the profiler always after the JVM start.
          This is useful for running testcases.
      memory=true|false (default=true)
          Disable ObjectAlloc and ObjectRelease events.
      tracer=true|false (default=false)
          Enable MethodEntry and MethodExit events of Exception and Erorr classes
  </literallayout>
            </listitem>
          </itemizedlist></para>
  
        <para>To weak up this interceptor you would have to use the MBean</para>
      </sect2>
    </sect1>
  
    <sect1 id="JVMTI">
      <title>JVMTI - Java Virtual Machine Tool Interface</title>
  
      <para>JVMTI is the replacement for JVMTI after Java 5.</para>
  
      <para>We will re implement events defined at JVMPI(<xref
      linkend="JVMPI" />), but for now we are only using this to capture memory
      profiler snapshots (<xref linkend="memory-snapshot" />)</para>
  
      <sect2>
        <title>Options</title>
  
        <para><itemizedlist>
            <listitem>
              <para>Add the -agentlib:jbossAgent</para>
  
              <literallayout>
              There are no options at this time
  </literallayout>
            </listitem>
          </itemizedlist></para>
  
        <para>The MBean responsible for the control of the life cycle for the
        memory profiler has also some utility methods</para>
  
        <itemizedlist>
          <listitem>
            <para>forceGarbageCollector</para>
          </listitem>
  
          <listitem>
            <para>getLoadedClasses</para>
          </listitem>
  
          <listitem>
            <para>getObjects(Class)</para>
          </listitem>
        </itemizedlist>
      </sect2>
    </sect1>
  
    <sect1>
      <title>How it's compared to commercial tools</title>
  
      <para>The first thing that differs JBossProfiler is its conception based
      in LogFiles instead of wired protocols. This gives the tool more power
      plus enabling remote teams to analyze remote scenarios with minimal setup
      on servers.</para>
  
      <para>Usually I say that JBossProfiler has <emphasis role="bold">enough
      </emphasis>features to find bottlenecks.</para>
  
      <para>Features that both JBossProfiler and Commercial Tools will
      have:</para>
  
      <itemizedlist>
        <listitem>
          <para>Tree Navigation over the graph of callings</para>
        </listitem>
  
        <listitem>
          <para>Graph visualization of the graph of callings</para>
        </listitem>
  
        <listitem>
          <para>% Identification of Bottlenecks</para>
        </listitem>
      </itemizedlist>
  
      <para>There are of course features unique to JBossProfiler. Original
      ideas:</para>
  
      <itemizedlist>
        <listitem>
          <para>LogFile based</para>
  
          <para>This is idea to support teams, where the problem is away from
          your analysis tool.</para>
  
          <para>Also, this seems to increase the power of analysis. Usually you
          can analyze more data with JBossProfiler.</para>
        </listitem>
  
        <listitem>
          <para>Memory Profiler based in Snapshot using only a server
          MBean</para>
  
          <para>A commercial profiler requires a front-end installed in order to
          create the snapshot.</para>
        </listitem>
  
        <listitem>
          <para>Object allocations and Object Releases referenced to
          methods</para>
  
          <para>I haven't seen that feature in any other profiler</para>
        </listitem>
      </itemizedlist>
  
      <para>Usually commercial profilers are developer's tools, and of course
      they have more developers features like nice integrations with IDEs and
      Debuggers and views that can and sell lot of functionality. Well, we don't
      want to compete with commercial profilers but we want to offer a nice view
      about what is happening with your code and understand what is
      happening.</para>
  
      <para>Sometimes of course is more comfortable to use commercial tools but
      you can always have the information you need with JBossProfiler</para>
    </sect1>
  </chapter>
  
  
  1.1      date: 2006/11/10 17:40:20;  author: csuconic;  state: Exp;jboss-profiler/docbook/en/modules/memory.xml
  
  Index: memory.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <chapter id="memory">
    <title>Memory Profiler</title>
  
    <sect1 id="memconcept">
      <title>Concept</title>
  
      <para>The concept of the memory profiler is almost the same as the runtime
      profiler. The only difference is that you can take several snapshots of
      your memory during an execution.</para>
  
      <para>You can extract a snapshot by using the MBean( <xref
      linkend="usembean" />)</para>
  
      <para>The CPU is frozen while the snapshot is being extracted, what
      usually takes</para>
    </sect1>
  
    <sect1 id="memory-snapshot">
      <title>Capturing a Snapshot</title>
  
      <para>Steps to extract a snapshot:</para>
  
      <para>- Add jbossAgent.dll to your path or libjbossAgent.so to your
      LD_LIBRARY_PATH</para>
  
      <para>- Add -agentlib:jbossAgent to your JVM 5 command line. (Java 5 at
      least is required as JVMTI was introduced on Java 5)</para>
  
      <para>- Go to JMX Console (http://localhost:8080/jmx-console) and look for
      JBossProfiler:JVMTI MBean (mbean=JVMTIClass)</para>
  
      <para>- Call heapSnapshot from JVMTIClass MBean. use P1 as a prefix, and
      P2 as the extension. For instance P1=/tmp/log, and P2=mem. This will
      create three files starting with log under /tmp, with
      extension=.mem</para>
  
      <para>- Use the JbossProfiler application
      (http://localhost:8080/jboss-profiler) after you have installed
      jboss-profiler.war to your /deploy directory.</para>
    </sect1>
  
    <sect1 id="file-formats">
      <title>File formats</title>
  
      <para>All the files used in the memory profiler are simple text files, CVS
      like.</para>
  
      <para>This way you can write your own tool to analyze the snapshot
      generated.</para>
  
      <sect2>
        <title>Classes</title>
  
        <para><itemizedlist>
            <listitem>
              <para>tagClass – An unique count id for the class</para>
            </listitem>
  
            <listitem>
              <para>signature – The JNI signature for the class</para>
            </listitem>
  
            <listitem>
              <para>tagClassLoader – The unique object id for the
              classLoader</para>
            </listitem>
          </itemizedlist></para>
  
        <para>Example:</para>
  
        <para><literallayout>tagClass,signature,tagClassLoader
  1,Ljava/io/BufferedWriter;,0
  2,Ljava/util/Collections$ReverseComparator;,0
  3,Ljava/lang/StringCoding$StringDecoder;,0
  </literallayout></para>
      </sect2>
  
      <sect2>
        <title>Objects</title>
  
        <para><itemizedlist>
            <listitem>
              <para>ObjectTag – The Unique Count Id of an object</para>
            </listitem>
  
            <listitem>
              <para>ClassTag – The Unique Count Id of the declaring class for
              this object</para>
            </listitem>
  
            <listitem>
              <para>Size – The size in bytes for this object</para>
            </listitem>
          </itemizedlist></para>
  
        <para>Example:</para>
  
        <para><literallayout>objectTag,classTag,size
  1338,59,480
  1339,106,88
  1340,106,88
  1341,106,88
  </literallayout></para>
      </sect2>
  
      <sect2>
        <title>References</title>
  
        <para><itemizedlist>
            <listitem>
              <para>tagReferrer – ObjectTag for the object owning a
              reference</para>
            </listitem>
  
            <listitem>
              <para>tagReferred – ObjectTag for the object referenced</para>
            </listitem>
  
            <listitem>
              <para>index – JVMTI sends this count that I didn't find any usage
              for this. It’s here for future usage.</para>
            </listitem>
          </itemizedlist></para>
  
        <para>Example:</para>
  
        <para><literallayout>tagReferrer, tagReferee,index
  0,134,0
  0,168,0
  0,16,0
  0,270,0
  </literallayout></para>
      </sect2>
    </sect1>
  </chapter>
  
  
  1.1      date: 2006/11/10 17:40:20;  author: csuconic;  state: Exp;jboss-profiler/docbook/en/modules/jvmti.xml
  
  Index: jvmti.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <chapter id="jvmti">
    <title>JVMTIInterface</title>
  
    <sect1>
      <title>Features</title>
  
      <para>JVMTIInterface is class wrapping most features of JVMTI through a
      Java interface. Using this interface you can inquiry things you wouldn't
      be able using any regular Java API.</para>
  
      <para>Things like:</para>
  
      <itemizedlist>
        <listitem>
          <para>What are the current classes?</para>
        </listitem>
  
        <listitem>
          <para>What are the current objects of a given class?</para>
        </listitem>
  
        <listitem>
          <para>What is the memory state?</para>
        </listitem>
      </itemizedlist>
  
      <para>This is very useful to improve testcases. You could "lock" your
      memory setting an alarm if a test consumed more memory than expected. This
      is relatively easy to use and this chapter is going to show examples in
      how to do it.</para>
    </sect1>
  
    <sect1>
      <title>The API</title>
  
      <para>This section will show the most important methods part of the public
      interface. These methods are very useful on JUnit tests.</para>
  
      <para>Class <emphasis
      role="bold">org.jboss.profiler.jvmti.JVMTIInterface</emphasis></para>
  
      <table>
        <title></title>
  
        <tgroup cols="3">
          <colspec align="center" />
  
          <tbody>
            <row>
              <entry><emphasis role="bold">MethodName and
              Signature</emphasis></entry>
  
              <entry><emphasis role="bold">Description</emphasis></entry>
  
              <entry><emphasis role="bold">Exposed through
              MBean</emphasis></entry>
            </row>
  
            <row>
              <entry>Class getClassByName(String className)</entry>
  
              <entry>search for all classes and return the first class maching
              className</entry>
  
              <entry>N</entry>
            </row>
  
            <row>
              <entry>Object[] getReferenceHolders(Object [] objects)</entry>
  
              <entry>return all the objects holding references to the objects
              passed by parameter</entry>
  
              <entry>N</entry>
            </row>
  
            <row>
              <entry>Class[] getLoadedClasses()</entry>
  
              <entry>return all loaded classes</entry>
  
              <entry>N</entry>
            </row>
  
            <row>
              <entry>void notifyInventory(boolean notifyOnClasses, String
              temporaryFileReferences, String temporaryFileObjects,
              JVMTICallBack callback)</entry>
  
              <entry>navigate through the entire HEAP sending results to
              JVMTICallBack interface. This process needs temporary files during
              its collection.</entry>
  
              <entry>N</entry>
            </row>
  
            <row>
              <entry>Object[] getReferenceHolders(Object [] objects)</entry>
  
              <entry>return all the referenceHolders for the objects passed by
              parameter.</entry>
  
              <entry>N</entry>
            </row>
  
            <row>
              <entry>Class[] getLoadedClasses()</entry>
  
              <entry>return all loaded classes on the JVM.</entry>
  
              <entry>N</entry>
            </row>
  
            <row>
              <entry>Object[] getAllObjects(Class clazz)</entry>
  
              <entry>return all objects on a given class.</entry>
  
              <entry>N</entry>
            </row>
  
            <row>
              <entry>Object[] getAllObjects(String className)</entry>
  
              <entry>return all objects on all classes where
              class.getName().equals(className). This is in case more than one
              classLoader loads the same class.</entry>
  
              <entry>N</entry>
            </row>
  
            <row>
              <entry>void heapSnapshot(String basicFileName, String
              suffix)</entry>
  
              <entry>Exposes heap to files. Look at manual for more
              details.</entry>
  
              <entry>Y</entry>
            </row>
  
            <row>
              <entry>String exploreClassReferences(...)</entry>
  
              <entry>Report method. This method reports references to
              classes.</entry>
  
              <entry>Y</entry>
            </row>
  
            <row>
              <entry>String exploreObjectReferences(String className, int
              maxLevel, boolean useToString)</entry>
  
              <entry>Report method. Will show a reference tree for objects
              instanceof className.</entry>
  
              <entry>Y</entry>
            </row>
  
            <row>
              <entry>void forceReleaseOnSoftReferences()</entry>
  
              <entry>Will allocate memory until an OutOfMemoryException happens,
              release it, and forceGC. This will force SoftReferences to go
              away.</entry>
  
              <entry>Y</entry>
            </row>
  
            <row>
              <entry>void forceGC()</entry>
  
              <entry>Will force a FullGC by a JVMTI method (not System.gc) what
              guarantees a FullGC execution.</entry>
  
              <entry>Y</entry>
            </row>
  
            <row>
              <entry>String listClassesHTMLReport()</entry>
  
              <entry>Report Method. Will show duplications and every single
              loaded class on the JVM</entry>
  
              <entry>Y</entry>
            </row>
  
            <row>
              <entry>String inventoryReport()</entry>
  
              <entry>Report Method. Will show a summary of Objects allocations
              per class. This method is very useful to inspect number of objects
              and number of bytes for every single class on the system.</entry>
  
              <entry>Y</entry>
            </row>
  
            <row>
              <entry>String printObjects(String className)</entry>
  
              <entry>Report Method. Will show a summary of every single object
              instanceof ClassName.</entry>
  
              <entry>Y</entry>
            </row>
  
            <row>
              <entry>Map produceInventory()</entry>
  
              <entry>Returns a WeakHashMap&lt;Class,InventoryDataPoint&gt;
              summarizing the current JVM's inventory. This could be used by
              compareInventories and be used on JUnit tests making sure the
              system is not allocating more objects than expected.</entry>
  
              <entry>N</entry>
            </row>
  
            <row>
              <entry>boolean compareInventories(...)</entry>
  
              <entry>Compares two distinct Inventories validating expected
              boundaries defined by parameters.</entry>
  
              <entry>N</entry>
            </row>
          </tbody>
        </tgroup>
      </table>
    </sect1>
  
    <sect1>
      <title>Report example</title>
  
      <para>if you use inventoryReport for example, you would have this
      output:</para>
  
      <informaltable>
        <tgroup cols="3">
          <tbody>
            <row>
              <entry>Class</entry>
  
              <entry>#Instances</entry>
  
              <entry>#Bytes</entry>
            </row>
  
            <row>
              <entry>[C</entry>
  
              <entry>75194</entry>
  
              <entry>7294512</entry>
            </row>
  
            <row>
              <entry>[I</entry>
  
              <entry>2641</entry>
  
              <entry>3226560</entry>
            </row>
  
            <row>
              <entry>java.util.HashMap$Entry</entry>
  
              <entry>128603</entry>
  
              <entry>3086472</entry>
            </row>
  
            <row>
              <entry>java.lang.String</entry>
  
              <entry>111955</entry>
  
              <entry>2686920</entry>
            </row>
  
            <row>
              <entry>[Ljava.util.HashMap$Entry;</entry>
  
              <entry>31239</entry>
  
              <entry>2639088</entry>
            </row>
  
            <row>
              <entry>[Ljava.lang.Object;</entry>
  
              <entry>10456</entry>
  
              <entry>1798312</entry>
            </row>
  
            <row>
              <entry>java.util.HashMap</entry>
  
              <entry>31199</entry>
  
              <entry>1247960</entry>
            </row>
  
            <row>
              <entry>[B</entry>
  
              <entry>718</entry>
  
              <entry>1247680</entry>
            </row>
  
            <row>
              <entry>java.lang.reflect.Method</entry>
  
              <entry>12799</entry>
  
              <entry>1023920</entry>
            </row>
  
            <row>
              <entry>javax.management.modelmbean.DescriptorSupport$CaseIgnoreString</entry>
  
              <entry>45076</entry>
  
              <entry>721216</entry>
            </row>
  
            <row>
              <entry>org.jboss.mx.server.InvocationContext</entry>
  
              <entry>9054</entry>
  
              <entry>579456</entry>
            </row>
  
            <row>
              <entry>javax.management.modelmbean.DescriptorSupport</entry>
  
              <entry>19205</entry>
  
              <entry>307280</entry>
            </row>
  
            <row>
              <entry>[Ljava.lang.String;</entry>
  
              <entry>14340</entry>
  
              <entry>298104</entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>
    </sect1>
  
    <sect1>
      <title>Testing MemoryLeaks</title>
  
      <sect2>
        <title>ClassLoader Leakage</title>
  
        <para>This page shows why a classLoader reference would leak. Instead of
        putting all these details here, I will just point the URL as a
        reference:</para>
  
        <para><link linkend="???"><ulink
        url="http://wiki.jboss.org/wiki/Wiki.jsp?page=ClassLeakage">http://wiki.jboss.org/wiki/Wiki.jsp?page=ClassLeakage</ulink></link></para>
  
        <para>As you can see on the URL, the classLoader won't be released
        untill all your strong references are cleared. The only strong
        references to a class or classLoader you don't need to release are
        references to your own classes or your own classLoader. Like, if a user
        makes a reference to a User's class on its JAR, GC will be able to
        determine the whole group is self contained thus the package can be
        released from the memory.</para>
  
        <para>It's okay to make a reference for your user class, but if you are
        writting a framework or anything that will be used by super classLoaders
        using any sort of meta data and reflection, than you are highly
        ellegible of creating what we call a redeployment leak. That means a
        classLoader won't be garbage collected thus the class will never leave
        the memory.</para>
  
        <para>ideally all your references to a Class, ClassLoader needs to be a
        WeakReference, and references to reflection will need to be a
        SoftReference.</para>
  
        <para>If you read the wiki page in detail you will realize that is
        really hard to keep up with these constraints and if you don't have a
        testcase is very likely you will create a redeployment leak some
        day.</para>
  
        <para>First thing you need in your test is an artificial classLoader.
        JBossTest project has a super class (org.jboss.test.JBossMemoryTestCase)
        you can use as base for this kind of test. In particular you need to use
        the newClassLoaderMethod:</para>
  
        <programlisting>   protected static ClassLoader newClassLoader(Class anyUserClass) throws Exception
     {
        ... This will create a regular classLoader
     }
     
  </programlisting>
  
        <para>Than you have to execute your methods using this classLoader. You
        could call a super method (using reflection). At the end, release every
        single instance, you could call a forceGC and the classLoader would have
        been released.</para>
  
        <para>The secret on this type of test is to not use any strong reference
        (do not use imports to your class), and use getClassByName(String name).
        The class then is supposed to be released.</para>
  
        <para>The following list is a simplified but real example:</para>
  
        <programlisting>/**
   * This class requires -agentlib:jbossAgent on JVM arguments on the JVM for
   * working properly
   * 
   * @author csuconic
   * 
   */
  public class MemoryLeakTestCase extends TestCase {
  
    public void testSample() throws Exception {
      JVMTIInterface jvmti = new JVMTIInterface();
      ClassLoader loader = newClassLoader();
      Class theClass = loader.loadClass("org.jboss.serial.memory.test.SomePojo");
  
      jvmti.forceGC();
  
      // The class still on the memory
      assertNotNull(jvmti.getClassByName("org.jboss.serial.memory.test.SomePojo"));
  
      theClass = null;
      loader = null;
  
      jvmti.forceGC();
  
      assertNull(jvmti.getClassByName("org.jboss.serial.memory.test.SomePojo"));
  
    }
  
    /** Will create a ClassLoader to be used by the test */
    private static URLClassLoader newClassLoader() throws MalformedURLException {
  
      String dataFilePath = MemoryLeakTestCase.class.getResource("test")
          .getFile();
      String location = "file://"
          + dataFilePath.substring(0, dataFilePath.length()
              - "org.jboss.serial.memory.test".length());
  
      StringBuffer newString = new StringBuffer();
      for (int i = 0; i &lt; location.length(); i++) {
        if (location.charAt(i) == '\\') {
          newString.append("/");
        } else {
          newString.append(location.charAt(i));
        }
      }
      String classLocation = newString.toString();
  
      URLClassLoader theLoader = URLClassLoader.newInstance(new URL[] { new URL(
          classLocation) }, null);
      return theLoader;
    }
  
  }
  </programlisting>
  
        <para>With JVMTI you can inquire about the objects/classes inventory and
        assert about its expected state. As the classLoader wouldn't tell if you
        if a class is loaded or not, the only way to do so is using an API
        exposing DEBUG properties like JBossProfiler does through
        JVMTIInterface.</para>
  
        <para>If you look at the testcase above you will see these
        operations:</para>
  
        <itemizedlist>
          <listitem>
            <para>ClassLoader creation</para>
          </listitem>
  
          <listitem>
            <para>loadClassOperation</para>
          </listitem>
  
          <listitem>
            <para>forceGC</para>
          </listitem>
  
          <listitem>
            <para>assertionNotNull (using jvmti.getClassByName)</para>
  
            <para>So if the class was released by accident, like if something is
            not holding the reference by accident. (maybe a too weak
            scenario)</para>
          </listitem>
  
          <listitem>
            <para>releasing references</para>
          </listitem>
  
          <listitem>
            <para>forceGC</para>
          </listitem>
  
          <listitem>
            <para>assertNull operation (using jvmti.getClassByName)</para>
  
            <para>At this point there isn't any reference to the classLoader (or
            to the class). So if a GC happens the class will be released from
            the memory.</para>
          </listitem>
        </itemizedlist>
  
        <para>This example is relatively simple and you could improve a lot on
        top of that. If you need more concrete examples look at projects like
        JBoss AOP, JBoss Serialization and JBoss MC. All these projects will
        have a MemoryLeakTestCase validating scenarios like this.</para>
      </sect2>
  
      <sect2>
        <title>Objects Leakage</title>
  
        <para>Objects leakages are much easier to understand. But the problem
        is, everybody think it's so easy to understand that every programmer in
        the universe think that the GarbageCollection is always sufficient to
        capture our garbage. Well, in few words the GC is capable to capture our
        garbage, not our crap :-)</para>
  
        <para>Most source of MemoryLeaks are Collections holding references when
        they are supposed to release the information. Most times this happens
        through publish/subscriber routines loosing some communication. Some
        occasions the linked list scenario could also happen by accident.</para>
  
        <para>The API to test Object Leakages is pretty simple, just two
        methods:</para>
  
        <itemizedlist>
          <listitem>
            <para>WeakHashMap&lt;Class,InventoryDataPoint&gt;
            produceInventory</para>
          </listitem>
  
          <listitem>
            <para> boolean compareInventories</para>
  
            <para>Parameters:</para>
  
            <itemizedlist>
              <listitem>
                <para>reportOutput You could set System.out here. The location
                where logging information is going to be sent.</para>
              </listitem>
  
              <listitem>
                <para>map1 The first snapshot</para>
              </listitem>
  
              <listitem>
                <para>map2 The second snapshot</para>
              </listitem>
  
              <listitem>
                <para>ignoredClasses Classes you want to ignore on the
                comparisson. Used to ignore things you know are going to be
                produced and you don't have control over the testcase</para>
              </listitem>
  
              <listitem>
                <para>prefixesToIgnore Same thing as classes, but every classes
                starting with these prefixes are going to be ignored</para>
              </listitem>
  
              <listitem>
                <para>expectedIncreases An array of InventoryDataPoint with the
                maximum number of instances each class could be
                generating.</para>
              </listitem>
            </itemizedlist>
          </listitem>
        </itemizedlist>
  
        <para>This is an example on how to validate memory leaks:</para>
  
        <programlisting>public void testNotifyOnObjects() throws Exception {
    class TestClass {
  
    }
  
    JVMTIInterface jvmti = new JVMTIInterface(); // The JVMTIWrapper used to
                                                  // produce inventories
  
    TestClass keepr = new TestClass(); // at least one instance, so point2
                                        // won't be null
  
    Map firstMap = jvmti.produceInventory(); // The inventory of classes, this
                                              // is
                                              // HashMap&lt;Class,InventoryDataPoint&gt;
  
    TestClass[] tests = new TestClass[1000];
    for (int i = 0; i &lt; 1000; i++) {
      tests[i] = new TestClass(); // allocating 1000 objects
    }
  
    Map secondMap = jvmti.produceInventory(); // the second inventory
  
    InventoryDataPoint point1 = (InventoryDataPoint) secondMap
        .get(TestClass.class);
    InventoryDataPoint point2 = (InventoryDataPoint) firstMap
        .get(TestClass.class);
  
    assertEquals(1000, point1.getInstances() - point2.getInstances()); // you
                                                                        // can
                                                                        // manually
                                                                        // compare
                                                                        // it
  
    assertTrue(jvmti
        .compareInventories(System.out, firstMap, secondMap,
            new Class[] { WeakHashMap.class }, new String[] {
                "[Ljava.util.WeakHashMap$Entry;", "java.lang.ref" },
            new InventoryDataPoint[] { new InventoryDataPoint(TestClass.class,
                2000) }));
    assertFalse(jvmti
        .compareInventories(System.out, firstMap, secondMap,
            new Class[] { WeakHashMap.class }, new String[] {
                "[Ljava.util.WeakHashMap$Entry;", "java.lang.ref" },
            new InventoryDataPoint[] { new InventoryDataPoint(TestClass.class,
                100) }));
  
  }
  </programlisting>
  
        <para>Basically this test is:</para>
  
        <orderedlist>
          <listitem>
            <para>Saving a first memory inventory snapshot, calling
            produceInventory</para>
          </listitem>
  
          <listitem>
            <para>Doing some operations. (allocating memory)</para>
          </listitem>
  
          <listitem>
            <para>Doing comparissons on the snapshot</para>
          </listitem>
        </orderedlist>
  
        <para>Anything allocating more memory than expected is going to generate
        a failure on this testsuite.</para>
  
        <para>With a testcase like that you are locking the doors of memory
        leaks in your system.</para>
      </sect2>
    </sect1>
  </chapter>
  
  
  1.1      date: 2006/11/10 17:40:20;  author: csuconic;  state: Exp;jboss-profiler/docbook/en/modules/compiling.xml
  
  Index: compiling.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <chapter id="compiling">
    <title>How to Compile Native Libraries</title>
  
    <para>There are two native libraries for JBossProfiler, JVMTI and
    JVMPI.</para>
  
    <para>JVMPI is a API released for JVM 1.4, and is being replaced by a newer
    and better version called JVMTI.</para>
  
    <para>We are still supporting both versions as JVMPI is the only native way
    to extract performance metrics from JVM 1.4.</para>
  
    <sect1>
      <title>Requirements</title>
  
      <para>In case you are using windows, you will need cygwin installed in
      order to compile either JVMPI or JVMTI.</para>
  
      <para>You will then need g++ and gcc installed. </para>
  
      <para>You also need JAVA_HOME defined to a valid JDK 1.4 (JVMPI) or JDK
      1.5 (JVMPI and JVMTI), as some includes will be used under JDK
      directory.</para>
    </sect1>
  
    <sect1 id="compiling-JVMPI">
      <title>Compiling JVMPI Module</title>
  
      <para>Under jvmti-lib there are one directory for each platform. (linux,
      solaris, macos and win32).</para>
  
      <para>Go the directory that represents your platform and call ./compile.sh.</para>
    </sect1>
  
    <sect1 id="compiling-JVMTI">
      <title>Compiling JVMTI Module</title>
  
      <para>Under jvmpi-lib there are one directory for each platform. (linux,
      solaris, macos and win32).</para>
  
      <para>Go the directory that represents your platform and call ./compile.sh.</para>
      <para></para>
    </sect1>
  </chapter>
  
  



More information about the jboss-cvs-commits mailing list