Department of Computer Science


(Version 2.1.1 October, 2005)

Every other CPU has a machine level debugger/viewer.  Why not one for the Java Virtual Machine?


The JVMViewer simulates JVM (Java Virtual Machine)  instructions of a method in a class.  It will show you how each instruction in a method is interpreted. Well almost.  Please review the caveats below.

Its primary purpose is to debug simple programs written with the Jasmin Assembler to show what actually is happening.  It also shows the execution of (most) methods of  a compiled Java program.


  1. Installing  and running the JVMViewer
  2. Loading a class file
  3. Selecting a method
  4. Selecting parameters
  5. Stepping through
  6. Caveats
  7. References, source code, javadocs
  8. Changes

Installing and running the JVMViewer

  1. Download jvmem.jar and save it in the directory where you normally keep your .class files.
  2. In  Windows, or Unix/Linux, bring up the Dos Command Prompt / UNIX Terminal and change directory to the directory containing your  .class files. Start the JVMViewer by entering

  3.           java -cp jvmem.jar jvmem.JVMViewer 

    The JVMViewer is found in the jvmem package contained in the jvmem.jar file. 

    The window should look like

pic 2

  1. You can start the JVMViewer in other ways, depending upon your mood.

Loading a class file

     In the File submenu, Open the  .class file that you want to view.  You can browse to any directory that contains a .class file.  While clicking on a .class file icon is preferred, you can, of course, type in a class file name with or without the .class suffix.
The class file will be verified by the JVM loader.  Since there is no guarantee that a jasmin program is well behaved, and our interpreter assumes that it is, this step is necessary. (Adding a float and an integer is not a good idea.)  The display will look like

pic 3

    If you want to to load a class in a package,  you must first get to the directory where the package subdirectory is located.  Then type in  packageName.ClassName.   For example, if from the directory myprogs you can execute java myPackage.myClass, then, to load this class, you would enter in  myPackage.myClass for the file name while in the directory myprogs.

Selecting a method

From the Method submenu, select a method.  You can distinguish between static methods and instance methods, since the latter are highlighted.  The screen will then show the object code, the stack size, and the maximum number of local variables.  This is shown in the beginning of the first figure.

Selecting Parameters 

  1. Instance methods must have an object associated with it.  The JVMViewer will create an object; it will be passed in as the first parameter.  Note: at this time, objects must have the default constructor (the one with no parameters).

  2. Required data for the parameters, if any, can be passed by selecting from the Parameters submenu.  A dialog will prompt you for the type of parameter. 

    1. For the primitive types int, char, float, long, double and boolean, you should have no problem passing in data. (The other primitive types can be easily implemented.  But  why?)

    2. For the String type, just type in the text box.  Note that pressing OK without entering any data will be the empty string "", not null.  (Is there any reason to input null?)

    3. For object types, a message will confirm that the object has been created.  That is, if the class for the object has the default constructor (the one with no parameters).  It will complain if it cannot create such an object.  Thus, we cannot interpret methods that pass an File object (at least for this version).

    4. Arrays of  int[]char[], float[]String[], and AnyObject[] can also be passed as parameters.  An array of strings will be single words.  For an array of objects, a dialog box will ask for the size of the array.  The class for the object must have the default constructor. Pressing OK without entering any array data will create an array with 0 elements.  You cannot pass null as a parameter.

      The String[] parameter allows us to execute main methods.  Try it.
  1. Once all the parameters have  been filled in, the interpreter will begin execution.  The display will be similar to the first figure. The  program counter (pc) will be a at location 0 of the instructions.  The instruction to be executed is displayed. The stack (any data above ----------------) will be empty.  The values of the parameters will be shown in the first local variables.  Integers and floats are displayed as such.  Characters and booleans are converted to their integer values.  Longs and doubles take up two local variables; the higher variable value is shown as --. References to arrays and objects are shown as -> array/object.  Any local variable value that is either undefined or contains null is shown as --.
The JVMViewer will complain if it cannot pass a particular parameter type.

Stepping Through

  1. Press the Step button to execute a machine instruction.  After execution, the next instruction to be executed is shown.  The stack will be shown above above ---------------- and the values of the local variables will be shown below.

  2. The default is to execute one machine instruction at a time, though you may change that value.  In particular you can choose "one after another" in which the interpreter continuously executes an instruction about once per second.  You can stop this by changing the step size to a number; in particular, selecting Execute no instructions will stop execution.

  3. When the method completes by one of the return's, the interpreter will show the value returned, if any.  The null value is shown as --
  1. Since the JVMViewer is using Java's capability for reflection (Java can call a method by naming it during execution), methods must be public so that the JVM can find the method.   If the method is not public, and we try to interpret an invokestatic or invokevirtual instruction calling it, we'll get a message such as  Internal error for invokestatic: java.lang.NoSuchMethodException: BCDFinal.bcdtoi(char)
  2. Simply make sure that all the methods called are public.

  3. Most, but not all,  instructions can be interpreted.  To see which ones that aren't, run
          java -cp jvmem.jar jvmem.Instructions none
    This will list the unimplemented instructions, such as the ever popular instruction  monitorenter. If you want to see the list of instructions that are implemented, run
        java -cp jvmem.jar jvmem.Instructions

References, source code, javadocs
  1. This all started with the desire to write assembly code for the Java Virtual Machine.  Looking at architectures may be fine, but writing code at a low level is an eye-opener. 
    1. For the assembler, look at the jasmin site, or download  here.
    2. Detailed explanations of the machine instructions from the old Jasmin site.  If you can't get to it, try Sun's site.
    3. Learning to write simple code for the JVM is easy.  Take a look at my  tutorial.  For more details, you can look at my notes for the course that I taught at Montclair State.
  2. Source code, in a zip file.  All files are in the package jvmem, a subdirectory of the project directory jvmming.
  3. Javadocs for the source code.  There may be some interesting comments.
  1. Version 2.1.1:
    1. Turned off Method and Parameter Menu when File Open
    2. Fixed the creation of a new object by faking the object on the stack  
    3. Catch verify error when loading
    4. Catch exceptions when calling methods
    5. Get/put (static) field can work with booleans
    6. Now compiled using Java 1.5.  (Not using 1.5?  Then use Version 2.0.1. jsut below)
  2. Version 2.0.1:
    1. The JVMViewer can load a .class file from any directory.  You no longer have to specify a class path to directories.
    2. The JVMViewer can load classes found in packages.   packageName.className must be typed in at the File prompt  while in the directory containing the package/directory packageName
    3. Most instructions  have been implemented.
    4. Bug fix for fcmpg and fcmpgl.  (I branched the wrong way.)
    5. A  class can be dumped  by selecting Methods/Class file.
  3. Version 1.0.1:
    1. A counter for the number of instructions executed is displayed.

Carl E. Bredlau
Department of Computer Science
College of Science and Mathematics
Montclair State University
1 Normal Avenue
Montclair, NJ  07043