Saturday, April 23, 2011

Dissection of Java Process

Dissection of Java Process


Every process occupies OS resources and each process has a unique process identifiers. Operating system is  responsible for managing and allocating process ids. To access the list of process currently manage by the OS is varying from one OS to other.
List of process currently running on windows operating system can be obtain by executing tasklist.exe command.

If we want only those processes which is running under JVM then we have to filter the output generated by tasklist.exe out as follow
Tasklist.exe /M java*                                                           

When we run the JConsole.exe (A Utility program which is available in JDK), a Connection dialog of JConsole will list all (process which is accessible to the logged in user) java processes running on current JVM (there is provision to connect remote JVM and obtain the list of process running on remote machine by passing appropriate credentials).




Similarly we can obtain the same list of process by running JPS.exe utility available in JDK.


 On Linux operating system the list of process can be obtain by executing ps commands.



Java provides standard way to access process relate information irrespective to the underlying OS using java.lang.management package.
The ManagementFactory class is a factory class for getting managed beans for the Java platform. This class consists of static methods each of which returns one or more platform MXBean(s) representing the management interface of a component of the Java virtual machine.

Retrieve Process & JVM related information associated with current process.


ManagementFactory factory provides a static method ManagementFactory.getRuntimeMXBean()  to obtain the runtime beans. Process id required to analyze the memory footprint with the help of JConsole.exe.

Code Snippet 1:

Partial code snippet to generate the Process Tab
protected JComponent makeProcessPanel() throws UnsupportedLookAndFeelException
    {

        JPanel panel = new JPanel(false);
        panel.setLayout(new GridLayout(0, 1, 0, 0));

RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();

        String[] name = runtimeMXBean.getName().split("@");
        JLabel label_1 = new JLabel("Process Id : " + name[0]);
        label_1.setHorizontalAlignment(SwingConstants.CENTER);
        label_1.setFont(new Font("Segoe UI", Font.BOLD, 14));
        panel.add(label_1);

        JLabel label_2 = new JLabel("Process Running on : " + name[1]);
        label_2.setHorizontalAlignment(SwingConstants.CENTER);
        label_2.setFont(new Font("Segoe UI", Font.BOLD, 14));
        panel.add(label_2);

        JLabel label = new JLabel("VM Name : " + runtimeMXBean.getVmName());
        label.setHorizontalAlignment(SwingConstants.CENTER);
        label.setFont(new Font("Segoe UI", Font.BOLD, 14));
        panel.add(label);

JLabel label_3 = new JLabel("VM Version : " + runtimeMXBean.getVmVersion());
        label_3.setHorizontalAlignment(SwingConstants.CENTER);
        label_3.setFont(new Font("Segoe UI", Font.BOLD, 14));
        panel.add(label_3);

JLabel label_4 = new JLabel("VM Vendor : " + runtimeMXBean.getVmVendor());
        label_4.setHorizontalAlignment(SwingConstants.CENTER);
        label_4.setFont(new Font("Segoe UI", Font.BOLD, 14));
        panel.add(label_4);

        return panel;
    }

Retrieve Operating System related information associated with current process.


ManagementFactory factory provides a static method ManagementFactory.getOperatingSystemMXBean() by which we obtain the platform specific manage beans. The name of operating system, Architectural details of the processor, Number of processor etc. cab be obtain using operating system bean.
Example:
1)      Display OS details on about dialog.
2)      Application needs auto configuration as per the type of the operating system and number of processor and type of processor architecture etc.

Code Snippet 2:

Partial code snippet to generate the OS Tab
protected JComponent makeOSPanel()
    {
        JPanel panel = new JPanel(false);
        panel.setLayout(new GridLayout(4, 1));

 OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();

JLabel lnlOsName = new JLabel("Operating System :" + operatingSystemMXBean.getName());
        lnlOsName.setFont(new Font("Segoe UI", Font.BOLD, 14));
        lnlOsName.setHorizontalAlignment(SwingConstants.CENTER);
        panel.add(lnlOsName);
        JLabel lblArch = new JLabel("Architecture : " + operatingSystemMXBean.getArch());
        lblArch.setFont(new Font("Segoe UI", Font.BOLD, 14));
        lblArch.setHorizontalAlignment(SwingConstants.CENTER);
        panel.add(lblArch);
        JLabel lblProcessor = new JLabel("Number of Processor :" + operatingSystemMXBean.getAvailableProcessors());
        lblProcessor.setFont(new Font("Segoe UI", Font.BOLD, 14));
        lblProcessor.setHorizontalAlignment(SwingConstants.CENTER);
        panel.add(lblProcessor);

        return panel;
    }

Retrieve Heap memory status associated with current process.


Each process requires memory to execute the task. When new object is created a memory is allocated to the object. Once the object out of scope and no more references to the heap object then garbage collector free the memory allocated to the object. ManagementFactory factory provides a static method ManagementFactory.getMemoryMXBean to obtain the MemoryMXBean by which we can access the Heap and Non Heap memory usage.



Code Snippet 3:

Partial code snippet to generate the Memory Tab
private JComponent makeMemoryPanel()
    {
        JPanel panel = new JPanel(false);
        panel.setLayout(new GridLayout(0, 2));
        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
      
        JLabel lblHeapMemory = new JLabel("Heap Memory Usage  " );
        lblHeapMemory.setBackground(new Color(255, 255, 255));
        lblHeapMemory.setFont(new Font("Segoe UI", Font.BOLD, 14));
        lblHeapMemory.setHorizontalAlignment(SwingConstants.CENTER);
        panel.add(lblHeapMemory);
      
        JPanel heappanel = new JPanel();
        heappanel.setLayout(new GridLayout(0, 1, 0, 0));
  
        memoryUsage(heappanel, memoryMXBean.getHeapMemoryUsage());
        panel.add(heappanel);
       
        panel.add(new JLabel(""));
        panel.add(new JLabel(""));
       
        JLabel lblNonHeapMemory = new JLabel("Non Heap Memory Usage  " );
        lblNonHeapMemory.setFont(new Font("Segoe UI", Font.BOLD, 14));
        lblNonHeapMemory.setHorizontalAlignment(SwingConstants.CENTER);
        panel.add(lblNonHeapMemory);
       
        JPanel nonheapPanel = new JPanel();
        nonheapPanel.setLayout(new GridLayout(0, 1, 0, 0));
        memoryUsage(nonheapPanel, memoryMXBean.getNonHeapMemoryUsage());
       
        panel.add(nonheapPanel);
        return panel;
    }

private void memoryUsage(JPanel panel, MemoryUsage heapMemoryUsage)
    {
     
        JLabel lblinit = new JLabel("Init : " +heapMemoryUsage.getInit());
        lblinit.setBackground(new Color(255, 255, 255));
        lblinit.setFont(new Font("Segoe UI", Font.BOLD, 14));
        lblinit.setHorizontalAlignment(SwingConstants.LEFT);
        panel.add(lblinit);
       
        JLabel lblUsed = new JLabel("Used : " +heapMemoryUsage.getUsed());
        lblUsed.setBackground(new Color(255, 255, 255));
        lblUsed.setFont(new Font("Segoe UI", Font.BOLD, 14));
        lblUsed.setHorizontalAlignment(SwingConstants.LEFT);
        panel.add(lblUsed);                                  
       
JLabel lblCommited = new JLabel("Committed : " + heapMemoryUsage.getCommitted());
        lblCommited.setBackground(new Color(255, 255, 255));
        lblCommited.setFont(new Font("Segoe UI", Font.BOLD, 14));
        lblCommited.setHorizontalAlignment(SwingConstants.LEFT);
        panel.add(lblCommited);
       
        JLabel lblMax = new JLabel("Committed : " +heapMemoryUsage.getMax());
        lblMax.setBackground(new Color(255, 255, 255));
        lblMax.setFont(new Font("Segoe UI", Font.BOLD, 14));
        lblMax.setHorizontalAlignment(SwingConstants.LEFT);
        panel.add(lblMax);
    }

Retrieve Thread information associated with current process.

Java provides Software Level threading. . ManagementFactory factory provides a static method ManagementFactory.getThreadMXBean() to obtain the ThreadMXBean by which we can access the thread related information like number of thread currently running, Current Thread CPU Time and Current Thread User Time etc.

Code Snippet 4:

Partial code snippet to generate the Thread Tab
private JComponent makeThreadPanel()
    {

        JPanel panel = new JPanel(false);
        panel.setLayout(new GridLayout(4, 1));
         ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        JLabel lblThreadCount = new JLabel("Thread Count:" + threadMXBean.getThreadCount());
        lblThreadCount.setFont(new Font("Segoe UI", Font.BOLD, 14));
        lblThreadCount.setHorizontalAlignment(SwingConstants.CENTER);
        panel.add(lblThreadCount);
      
        JLabel lblCurrentThreadCpuTime = new JLabel("Current Thread CPU Time:" + threadMXBean.getCurrentThreadCpuTime()+"");
        lblCurrentThreadCpuTime.setFont(new Font("Segoe UI", Font.BOLD, 14));
        lblCurrentThreadCpuTime.setHorizontalAlignment(SwingConstants.CENTER);
        panel.add(lblCurrentThreadCpuTime);

JLabel lblCurrentThreadUserTime = new JLabel("Current Thread User Time:" + threadMXBean.getCurrentThreadUserTime()+"");
lblCurrentThreadUserTime.setFont(new Font("Segoe UI", Font.BOLD, 14));
        lblCurrentThreadUserTime.setHorizontalAlignment(SwingConstants.CENTER);
        panel.add(lblCurrentThreadUserTime);
       
        return panel;
   
    }


Click here to download complete source code.


2 comments:

  1. Hey, gr8 article. It's Very informative and interesting.

    I had no clue about such things. so thanks for it.

    ReplyDelete
  2. hey thank you so much ya... very very informative and very well explained..

    ReplyDelete