Main

JRockit Archives

August 4, 2008

JRCMD Goes Remote (>=R27.1 edition) (Migrated from the old BEA blog)

This is an updated version of my JRCMD goes remote blog entry. In version R27 JRockit had a major overhaul of the MBeans used to expose JRockit specific manageability features. One major difference is that the JRockit specific features are not loaded into the platform MBean server by default. To load them, a specific MBean must first be created, which in turn will load the rest of the MBeans exposing the API. The MBeans also moved to a new domain: "bea.jrockit.management".

The MBean to load is the bea.jrockit.management:JRockitConsole MBean. This can be done by simply using the MBeanServerConnection, for example like this:

MBeanServerConnection#createMBean(
   "bea.jrockit.management.JRockitConsole", null);

The following example is an altered version of my old "JRCMD Goes Remote" blog that, just like the JRCMD, allows the performance counters and ctrl-break handlers to be read/executed - but remotely from another machine.


import java.lang.management.ManagementFactory;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.management.Attribute;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

/**
* Simple code example on how to execute ctrl-break handlers remotely.
*
* Usage: RemoteJRCMD -host -port -user -pass
* -command []
*
* All arguments are optional. If no command is specified, all performance
* counters and their current values are listed.
*
* @author Marcus Hirt
*/
public class RemoteJRCMD {
private final static String KEY_CREDENTIALS = "jmx.remote.credentials";
private final static String JROCKIT_PERFCOUNTER_MBEAN_NAME = "bea.jrockit.management:type=PerfCounters";
private final static String JROCKIT_CONSOLE_MBEAN_NAME = "bea.jrockit.management:type=JRockitConsole";
private final static String[] SIGNATURE = new String[] { "java.lang.String" };
private final static String DIAGNOSTIC_COMMAND_MBEAN_NAME = "bea.jrockit.management:type=DiagnosticCommand";


public static void main(String[] args) throws Exception {
HashMap commandMap = new HashMap();
commandMap.put("-host", "localhost");
commandMap.put("-port", "7091");
for (int i = 0; i < args.length; i++) {
if (args[i].startsWith("-")) {
StringBuilder buf = new StringBuilder();
int j = i + 1;
while (j < args.length && !args[j].startsWith("-")) {
buf.append(" ");
buf.append(args[j++]);
}
commandMap.put(args[i], buf.toString().trim());
i = j - 1;
}
}
executeCommand((String) commandMap.get("-host"), Integer
.parseInt(commandMap.get("-port")), commandMap.get("-user"), commandMap
.get("-password"), commandMap.get("-command"));
}

public static void executeCommand(String host, int port, String user,
String password, String command) throws Exception {
MBeanServerConnection server = null;
JMXConnector jmxc = null;
Map map = null;
if (user != null || password != null) {
map = new HashMap();
final String[] credentials = new String[2];
credentials[0] = user;
credentials[1] = password;
map.put(KEY_CREDENTIALS, credentials);
}
// Use same convention as Sun. localhost:0 means "VM, monitor thyself!"
if (host.equals("localhost") && port == 0) {
server = ManagementFactory.getPlatformMBeanServer();
} else {
jmxc = JMXConnectorFactory.newJMXConnector(
createConnectionURL(host, port), map);
jmxc.connect();
server = jmxc.getMBeanServerConnection();
}

System.out.println("Connected to " + host + ":" + port);

try {
server.getMBeanInfo(new ObjectName(JROCKIT_CONSOLE_MBEAN_NAME));
} catch (InstanceNotFoundException e1) {
server.createMBean("bea.jrockit.management.JRockitConsole", null);
}

if (command == null) {
ObjectName perfCounterObjectName = new ObjectName(
JROCKIT_PERFCOUNTER_MBEAN_NAME);
System.out.println("Listing all counters...");
MBeanAttributeInfo[] attributes = server.getMBeanInfo(
perfCounterObjectName).getAttributes();
System.out.println("Counter\tValue\n=======\t====");

String[] attributeNames = new String[attributes.length];
for (int i = 0; i < attributes.length; i++) {
attributeNames[i] = attributes[i].getName();
}
Iterator valueIter = server.getAttributes(perfCounterObjectName,
attributeNames).iterator();
while (valueIter.hasNext()) {
Attribute attr = (Attribute) valueIter.next();
System.out.println(attr.getName() + "\t=\t" + attr.getValue());
}
} else {
System.out
.println("Invoking the ctrl-break command '" + command + "'...");
ObjectName consoleObjectName = new ObjectName(DIAGNOSTIC_COMMAND_MBEAN_NAME);
Object[] params = new Object[1];
params[0] = command;
System.out.println("The CtrlBreakCommand returned: \n"
+ server.invoke(consoleObjectName, "execute",
params, SIGNATURE));
}

if (jmxc != null) {
jmxc.close();
}
}

private static JMXServiceURL createConnectionURL(String host, int port)
throws MalformedURLException {
return new JMXServiceURL("rmi", "", 0, "/jndi/rmi://" + host + ":" + port
+ "/jmxrmi");
}
}


The following example would list all the performance counters and their values on localhost on the default port (7091):

java RemoteJRCMD

The following example would start a 60 second JRA recording on a JRockit running at the host bitsy, port 7099, writing the resulting recording to a file called nisse.zip:

java RemoteJRCMD -command jrarecording filename=nisse time=60 -host bitsy -port 7091

And as always, don't forget to enable the JMX management agent of the JRockit you wish to monitor. You can enable the management agent by using the -Xmanagement option like so:

-Xmanagement:port=7091,ssl=false,authenticate=false

Creating Fully Featured JRA Recordings with 1.4 Based JRockits (Migrated from the old BEA blog)

One of the parts of Mission Control is the JRA (the JRockit Runtime Analyzer). The JRA is a powerful profiler that can tell you a lot about the performance bottlenecks in your application whilst keeping the overhead barely noticeable.

There are new options added to the JRA recordings almost every release. In recent releases of Mission Control the JRA wizard will check what capabilities the JRockit you are attempting to start a recording on has, and present you with configurable options accordingly. The problem is that the legacy protocol used when connecting to a 1.4 version of JRockit unfortunately does not support querying for the available parameters. Do not despair; there are still means of starting JRA recordings that contain all the new goodies. This is how:

There is a neat little command line tool called jrcmd that can be found in JROCKIT_HOME/bin. The jrcmd tool can be used to invoke commands on a locally running JRockit process. It works like this:

  1. Do JROCKIT_HOME/bin/jrcmd to list the JRockit processes on your machine.
  2. Pick your favourite one and do JROCKIT_HOME/bin/jrcmd <pid> help
  3. Pick the command you wish to know more about, for example JROCKIT_HOME/bin/jrcmd <pid> help startjrarecording
  4. Invoke the command with the settings of your choice.

In this case, the command we want to use is startjrarecording, and what we want to know is what parameters we can use on a particular JRockit when issuing the startjrarecording command.

On the windows box I'm currently on, it looks like this:

D:\jrockits\R27.3.0_R27.3.0-106_1.5.0>bin\jrcmd.exe
2640 com.jrockit.mc.rcp.start.MCMain

5012 jrockit.tools.jrcmd.JrCmd

 

Notice how it lists itself. In this case I'm interested in knowing the available commands on the JRockit currently running my Mission Control (com.jrockit.mc.rcp.start.MCMain), so I do:

D:\jrockits\R27.3.0_R27.3.0-106_1.5.0>bin\jrcmd.exe 2640 help
2640:
The following commands are available:
        kill_rmp_server
        start_rmp_server
        kill_management_server
        start_management_server
        checkjrarecording
        stopjrarecording
        startjrarecording
        print_object_summary
        memleakserver
        print_class_summary
        print_codegenlist
        run_optfile
        dump_codelayout
        dump_codelist
        dump_codemap
        print_utf8pool
        print_properties
        print_threads
        datadump_request
        runsystemgc
        runfinalization
        heap_diagnostics
        oom_diagnostics
        print_exceptions
        version
        timestamp
        command_line
        memprof
        sanity
        verbosity
        set_filename
        help
        print_memusage
For more information about a specific command use 'help '.
Parameters to commands are optional unless otherwise stated.

 

To find out what parameters are available to me when starting a jrarecording I do:

D:\jrockits\R27.3.0_R27.3.0-106_1.5.0>bin\jrcmd.exe 2640 help startjrarecording
2640:
Starts a JRA recording.
        filename           - name of the file to store JRA recording to
                             (string, jrarecording.xml)
        recordingtime      - length of the recording in seconds (int, 60)
        delay              - delay before starting recording in seconds (int,
                             0)
        methodsampling     - enable method sampling (bool, true)
        gcsampling         - enable gc information (bool, true)
        heapstats          - include heap statistics (bool, true)
        nativesamples      - include native code in sampling (bool, false)
        methodtraces       - include stack traces (bool, true)
        tracedepth         - depth of stack traces (int, 16)
        sampletime         - time between samples in milliseconds (int, 30)
        zip                - zip the recording (bool, true)
        hwsampling         - use hardware sampling if possible (bool, false)
        threaddump         - do full threaddumps at start and end of recordning
                             (bool, true)
        threaddumpinterval - also do threaddumps every 'n' interval (can be
                             specified as x[ns|ms|s]) (time, 0s)
        latency            - include latency analysis (bool, false)
        latencythreshold   - do not record events shorter than this number (can
                             be specified as x[ns|ms|s]) (time, 20ms)
        cpusamples         - sample cpu usage during the recording (bool,
                             true)
        cpusampleinterval  - cpu sample interval (can be specified as
                             x[ns|ms|s]) (time, 1s)

 

In this case I found out that I can indeed start up a recordings with new features such as latency analysis data on this particular JVM. To actually start such a recording I could for example write:

D:\jrockits\R27.3.0_R27.3.0-106_1.5.0>bin\jrcmd.exe 2640 startjrarecording laten
cy=true latencythreshold=20ms recordingtime=120s
2640:
JRA recording started.

Running Eclipse/Workshop on JRockit! (Migrated from the old BEA blog)

Within the next few days, Mission Control will be available for download directly into your IDE from an update site.  To fully take advantage of this, however, you need to run Eclipse on a JRockit. This blog is an update to an old blog of mine, which explains how and has a few very specific tips for the insanely rich or the ones working for BEA. ;)

Despite JRockit being an outspoken server side JVM, many long running client applications, like IDE's, actually run very well on JRockit. Running Eclipse on JRockit is no exception.

The easiest way to change the JVM on which to start Eclipse is by modifying the eclipse.ini file. You can also set the -vm on the command line used to start Eclipse. In windows you'd typically do that in the shortcut you use to launch Eclipse. Just using JRockit out of the box yields pretty good performance. Here is an example ini file:

-showsplash
org.eclipse.platform
-vm
D:\jrockits\R27.5.0_R27.5.0-111_1.5.0\bin\javaw.exe

You can usually get better performance by setting the initial heap size and the max heapsize to the same, thus bypassing the dynamic growing/shrinking of the heap:

-showsplash
org.eclipse.platform
-vm
D:\jrockits\R27.5.0_R27.5.0-110_1.5.0\bin\javaw.exe
-vmargs
-Xms384m
-Xmx384m

The insanely rich (or BEA employees) can run Eclipse on WLRT/deterministic GC (some would call this overkill) for a very smooth experience. This is the eclipse.ini I use myself:

-showsplash
org.eclipse.platform
-vm
D:\jrockits\R27.5.0_R27.5.0-110_1.5.0\bin\javaw.exe
-vmargs
-Xms384m
-Xmx384m
-XgcPrio:deterministic
-XpauseTarget:20
-XXcompactratio:1

One common pitfall is trying to use Sun specific flags, which would cause the JRockit launcher to exit right away, like for example -Xincgc or -Xbatch.

 

For more information:

August 15, 2008

Simple Exception Profiling with JRockit

Exception profiling is the business of finding out what exceptions are being thrown within your application and from where. In JRockit Mission Control you can find out how many exceptions have been thrown using JRA, and you can count the exceptions using the JRockit Management Console. Sadly there is no way of doing powerful exception profiling (i.e. looking at the stack traces for the exceptions, aggregating them and visualizing them directly in the JRockit Mission Control Client) just yet. This will be incorporated in a future version of Mission Control.

There is fortunately a way to do exception profiling with JRockit today. There are exception related verbose flags available in JRockit. These are examples on how to use them:

java -Xverbose:exceptions=debug ...

java -Xverbose:exceptions=trace ...

For a list of valid verbose options, please see http://e-docs.bea.com/jrockit/jrdocs/refman/optionX.html#wp999543.

Sometimes you really just want to enable this profiling for a little while, for example to avoid cluttering your log files. Then there is a nifty tool for JRockit called jrcmd you can use to turn on/off the exception profiling. It can be found under JROCKIT_HOME\bin\.

First use jrcmd to list all running java processes. Here is an example of what it may look like:

>jrcmd

10984 jrockit.tools.jrcmd.JrCmd

9396 C:\Java\eclipse3.3.1.1\plugins\org.eclipse.equinox.launcher_1.0.1.R33x_v200
70828.jar -data D:\Data\workspaces\workspace_3.3_facade -os win32 -ws win32 -arc
h x86 -showsplash -launcher C:\Java\eclipse3.3.1.1\eclipse.exe -name Eclipse --l
auncher.library C:\Java\eclipse3.3.1.1\plugins\org.eclipse.equinox.launcher.win3
2.win32.x86_1.0.2.R331_v20071019\eclipse_1021.dll -startup C:\Java\eclipse3.3.1.
1\plugins\org.eclipse.equinox.launcher_1.0.1.R33x_v20070828.jar -exitdata 1908_7
c -vm D:\jrockits\R27.4.0_R27.4.0-90_1.5.0\bin\javaw.exe -vmargs -Xms256m -Xmx51
2m -XgcPrio:deterministic -XpauseTarget:40 -Dosgi.bundlefile.limit=100 -jar C:\J
ava\eclipse3.3.1.1\plugins\org.eclipse.equinox.launcher_1.0.1.R33x_v20070828.jar

10976 Gegga

The numbers are the PIDs of the processes, and are used as the first argument to jrcmd to specify on what JRockit to address. You can use jrcmd to check what commands are available. Here is an example:

>jrcmd 10976 help
10976:
The following commands are available:
        kill_rmp_server
        start_rmp_server
        kill_management_server
        start_management_server
        checkjrarecording
        stopjrarecording
        startjrarecording
        print_object_summary
        memleakserver
        print_codegenlist
        print_class_summary
        run_optfile
        dump_codelayout
        dump_codelist
        dump_codemap
        print_utf8pool
        print_properties
        print_threads
        datadump_request
        runsystemgc
        runfinalization
        heap_diagnostics
        oom_diagnostics
        print_exceptions
        version
        timestamp
        command_line
        memprof
        sanity
        verbosity
        set_filename
        help
        print_memusage
For more information about a specific command use 'help <command>'.
Parameters to commands are optional unless otherwise stated.

Let's get more information about the print_exceptions command:

>jrcmd 10976 help print_exceptions

10976:
Enable printing of Java exceptions thrown in the VM.
To turn exception printing off completely you need to set exceptions = false
even if it was turned on by stacktraces = true. NOTE: This handler is
deprecated. The preferred way of displaying exceptions is to use the
'exceptions' logging module: -Xverbose:exceptions.
Values for the parameters can be "true|all|false"
true  - print all exception except java/util/EmptyStackException,
java/lang/ClassNotFoundException and
java/security/PrivilegedActionException
all   - print all exception
false - don't print exceptions
        exceptions  - print exceptions (string, false)
        stacktraces - print stacktrace (string, false)

Never mind that it is using an old handler in R27.6. The functionality will be the same. Let's enable the exception profiling:

>jrcmd 10976 print_exceptions stacktraces=true

If your application is throwing exceptions, you should now be seeing traces being logged to the console of that application. To turn off the exception logging, we do as the help suggests:

>jrcmd 10976 print_exceptions exceptions=false

Now, an even easier way to access the jrockit diagnostic commands is to use the JRockit Management Console. Simply connect the JRockit Management Console to the JRockit you wish to enable exception profiling on (from JRockit Mission Control). (Click the images to look at them in full size.)

start_console

Once the console is started, open the MBean Browser tab and move to the DiagnosticCommand MBean under bea.jrockit.management:

diagnostic_command

Double clicking on the ArrayList value of AllCommands will open up a list of all the available commands:

list_commands 
Now, select the operations tab and the executeDefault method that takes a String argument and press invoke. This will provide you with a dialog with push buttons for the arguments. In this case a single button with the label String. Press the String button and fill out the command. For example, print_exceptions stacktraces=true.

print_traces

Press Ok on both of the dialogs and exception profiling should now be enabled. To turn it off again, just invoke the operation again and enter print_exceptions exceptions=false, analogously with how you would use jrcmd.

An even easier way for Oracle employees is to pick up a recent internal build of JRockit and use the Diagnostic Command tab in the JRockit Management Console. :) Soon coming to a JRockit near you!

August 20, 2008

Getting JRockit Stack Dumps

Sometimes it may seem hard to get a simple thread stack dump from your JRockit. You may for instance have started it using the -Xnohup (-Xrs) option, or as a service. I'll list three different ways of looking at your threads in such situations.

The first way of getting your thread dump is to use jrcmd. My previous blog shows some basic jrcmd usage, so I'll just mention the command name: print_threads. Basic usage is jrcmd <PID> print_threads, for example jrcmd 780 print_threads.

The second way is to simply start the management console on the JRockit you want to monitor. After connecting the console to the JVM and switching to the threads view, you should be looking at something similar to the screen shot below.

thread_dumps

The third way is to use the MBean Browser's capability to invoke arbitrary operations on MBeans (also described in the last blog). Go to the MBean Browser in the JRockit Management Console. Select the DiagnosticCommand MBean, and switch to the operations tab. Select the execute operation that takes a String argument and returns a String. Click the String button, and fill in the argument print_threads.

invoking_dc

When you execute the operation you should see something like this:

after_dc

There are also ways of doing this programmatically, for example by using the JRockit JMAPI, or by invoking the execute operation programmatically as described in another old blog.

About JRockit

This page contains an archive of all entries posted to Marcus Hirt's Blog in the JRockit category. They are listed from oldest to newest.

JRockit Mission Control is the next category.

Many more can be found on the main index page or by looking through the archives.

Top Tags

Powered by
Movable Type and Oracle