Hi,
Based on the query of Magic Subscriber “fipnova51” we are writing this article. This article is very very important in case of Windows Service. Because if we run any Server like JBoss or WebLogic like a Windows Service then NONE of the JVM utilities like “jmap”, “jconsole” , “jps” …etc will work. So it becomes very difficult to collect the Thread Dump or Heap Dump of the Running Service.
We wrote an article using JMX to collect all the JVM details using JMX code “Remote JVM Analysis (Mini JConsole)“. Here we are extending the same program to make the JMX program to even collect the HeapDump whenever we want.
Step1). Make a Windows Service for example you can use the following Script to make your WebLogic Server as Windows Service…
echo off SETLOCAL set DOMAIN_NAME=Test_Domain set USERDOMAIN_HOME=C:bea103user_projectsdomainsTest_Domain set SERVER_NAME=AdminServer set WLS_USER=weblogic set WLS_PW=weblogic set PRODUCTION_MODE=true set JAVA_VENDOR=Sun set JAVA_HOME=C:bea103jdk160_05 set MEM_ARGS=-Xms1024m -Xmx1024m -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=127.0.0.1 set JAVA_OPTIONS=-Dweblogic.Stdout=C:bea103user_projectsdomainsTest_DomainASstdout.txt -Dweblogic.Stderr=C:bea103user_projectsdomainsTest_DomainASstderr.txt %MEM_ARGS% call "C:bea103wlserver_10.3serverbininstallSvc.cmd" ENDLOCAL
NOTE: Make sure that the -Dcom.sun.management.* flags are added properly in the JAVA_OPTIONS of the script.
Step2). Now You can also use the following Script to Uninstall your WebLogic Server Windows Service …
SETLOCAL set WL_HOME=C:bea103wlserver_10.3 rem *** Uninstall the service "%WL_HOME%serverbinbeasvc" -remove -svcname:"beasvc Test_Domain_AdminServer" ENDLOCAL
Step3). Now Write the following JMX code “GenerateHeapDump.java” inside some directory.
import java.util.Hashtable; import java.io.*; import javax.management.MBeanServerConnection; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; import javax.naming.Context; import java.lang.management.MemoryMXBean; import java.lang.management.ManagementFactory; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import javax.management.*; import javax.management.openmbean.CompositeDataSupport; public class GenerateHeapDump { private static MBeanServerConnection connection; private static JMXConnector connector; public static void Connection(String hostname, String port) throws IOException { Integer portInteger = Integer.valueOf(port); Hashtable h = new Hashtable(); JMXServiceURL address = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://"+hostname+":"+port+"/jmxrmi"); connector = JMXConnectorFactory.connect(address,null); connection = connector.getMBeanServerConnection(); System.out.println("GOT THE MBeanServerConnection---SUCCESSFULLY"); } private static void doGarbageCollection() throws Exception { ObjectName memoryMXBean=new ObjectName("java.lang:type=Memory"); connection.invoke(memoryMXBean,"gc", null, null); System.out.println("nnt------Garbage Collection Done Successfully-----"); } private static void getHeapDump(String fileName) throws Exception { ObjectName memoryMXBean=new ObjectName("com.sun.management:type=HotSpotDiagnostic"); Object[] params = new Object[] { "C:/WindowsService_Script/"+fileName, Boolean.TRUE }; String[] signature = new String[] { String.class.getName(), boolean.class.getName() }; Object result = connection.invoke(memoryMXBean, "dumpHeap" , params, signature); System.out.println("nt Heap Dump Generated to " +fileName); } public static void main(String[] args) throws Exception { String hostname = args[0]; String port = args[1]; Connection(hostname, port); System.out.println("nt----------Generating Heap Dump---------"); getHeapDump("HeapDump.hprof"); connector.close(); } }
Step4). Run your Windows Service and then compile and run your Program to generate the HeapDump.
C:WindowsService_Script>set PATH=c:bea103jdk160_05bin;%PATH%; C:WindowsService_Script>javac GenerateHeapDump.java C:WindowsService_Script>java GenerateHeapDump localhost 9999 GOT THE MBeanServerConnection---SUCCESSFULLY ----------Generating Heap Dump--------- Heap Dump Generated to HeapDump.hprof
Step5). Now you can see that the Heap Dump is generated as desired … 🙂
.
.
Thanks
Jay SenSharma
May 4th, 2011 on 9:39 pm
Hi,
I gor the following message when executing the java program (see below):
At first I though it was a classpath issue, then I used the program in the article ‘Remote JVM Analysis (Mini JConsole)’ and it executed successfully.
I suspect a system issue, like cannot generate heap dump because of too large file…
C:MyDocsMySources>java GenerateHeapDump my_host4444
GOT THE MBeanServerConnection—SUCCESSFULLY
———-Generating Heap Dump———
Exception in thread “main” javax.management.MBeanException: java.io.IOException: No such file or directory
at com.sun.jmx.mbeanserver.MBeanIntrospector.unwrapInvocationTargetException(MBeanIntrospector.java:283)
at com.sun.jmx.mbeanserver.MBeanIntrospector.invokeM(MBeanIntrospector.java:210)
at com.sun.jmx.mbeanserver.PerInterface.invoke(PerInterface.java:120)
at com.sun.jmx.mbeanserver.MBeanSupport.invoke(MBeanSupport.java:262)
at javax.management.StandardMBean.invoke(StandardMBean.java:391)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:836)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:761)
at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1427)
at javax.management.remote.rmi.RMIConnectionImpl.access$200(RMIConnectionImpl.java:72)
at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1265)
at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1360)
at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:788)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:305)
at sun.rmi.transport.Transport$1.run(Transport.java:159)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142)
at com.sun.jmx.remote.internal.PRef.invoke(Unknown Source)
at javax.management.remote.rmi.RMIConnectionImpl_Stub.invoke(Unknown Source)
at javax.management.remote.rmi.RMIConnector$RemoteMBeanServerConnection.invoke(RMIConnector.java:993)
at GenerateHeapDump.getHeapDump(GenerateHeapDump.java:41)
at GenerateHeapDump.main(GenerateHeapDump.java:51)
Caused by: java.io.IOException: No such file or directory
at sun.management.HotSpotDiagnostic.dumpHeap(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.jmx.mbeanserver.ConvertingMethod.invokeWithOpenReturn(ConvertingMethod.java:167)
at com.sun.jmx.mbeanserver.MXBeanIntrospector.invokeM2(MXBeanIntrospector.java:96)
at com.sun.jmx.mbeanserver.MXBeanIntrospector.invokeM2(MXBeanIntrospector.java:33)
at com.sun.jmx.mbeanserver.MBeanIntrospector.invokeM(MBeanIntrospector.java:208)
at com.sun.jmx.mbeanserver.PerInterface.invoke(PerInterface.java:120)
at com.sun.jmx.mbeanserver.MBeanSupport.invoke(MBeanSupport.java:262)
at javax.management.StandardMBean.invoke(StandardMBean.java:391)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:836)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:761)
at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1427)
at javax.management.remote.rmi.RMIConnectionImpl.access$200(RMIConnectionImpl.java:72)
at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1265)
at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1360)
at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:788)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:305)
at sun.rmi.transport.Transport$1.run(Transport.java:159)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
May 4th, 2011 on 10:02 pm
Hi fipnova51,
Just make sure that in “Line Number 39” of the above program whatever Directory is mentioned …Exist in your File System.
Object[] params = new Object[] { “C:/WindowsService_Script/”+fileName, Boolean.TRUE };
I can run the program Without any issue…. Just to reproduce the issue i removed the directory “C:/WindowsService_Script” from my file system and i can see that i am getting the same error as you are getting.
So just make sure that whatever Directory path you are specifying has read/write access and EXISTS
.
.
Keep Posting 🙂
Thanks
Jay SenSharma
May 4th, 2011 on 10:14 pm
Waouh it works now…
What I learnt from this is “always read the code” even if I’m not a dev.
Thanks for your help. I’ll try to improve this script on my needs.
Thanks again
September 25th, 2012 on 5:21 pm
Hi Jay,
Do we have any command-line usage to take “memory dump” in linux instead of using any tool utilities like jrcmd?
I just want to take memory dump.
thanks
September 26th, 2012 on 1:24 pm
You could try to use vmstat, which output something like:
[weblogic@middleware-magic nodemanager]$ vmstat
procs ———–memory———- —swap– —–io—- –system– —–cpu—–
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 1575716 41680 531508 0 0 69 8 61 66 1 1 97 1 0
Here you can see how much memory is free etcetera. There is also the Linux command free, for example,
[weblogic@middleware-magic nodemanager]$ free -m
total used free shared buffers cached
Mem: 3832 2294 1538 0 40 519
-/+ buffers/cache: 1734 2098
Swap: 3023 0 3023
You can also use dmidecode 2.11 as root (to find out Ram Speed, Make, Form Factor, Type and Other Information), for example,
[root@middleware-magic ~]# dmidecode 2.11 |more
# dmidecode 2.11
SMBIOS 2.4 present.
98 structures occupying 3645 bytes.
Table at 0x000E0010.
Handle 0x0000, DMI type 0, 24 bytes
BIOS Information
Vendor: Phoenix Technologies LTD
Version: 6.00
Release Date: 12/31/2009
Address: 0xEA2E0
Runtime Size: 89376 bytes
ROM Size: 64 kB
Characteristics:
ISA is supported
PCI is supported
PC Card (PCMCIA) is supported
PNP is supported
APM is supported
BIOS is upgradeable
BIOS shadowing is allowed
ESCD support is available
USB legacy is supported
….
September 27th, 2012 on 10:55 am
Thanks much Rene.
I’ll work on these possible ways for taking memory dumps, this helps me alot.
thanks