We had some issues of thread pile ups with production tomcat server so I wanted to setup some cron to to periodically check thread dumps and send alert email if something is wrong. To do this we need to take thread dumps in file from shell script but I am unable to do that. From shell I can issue KILL -3 <PID> at periodic intervals but the problem is that dump goes to catalina.out which contains GBs of data because of which pulling out only thread dump is painful process. Some discussion threads suggested usage of "jstack" and redirect output to a file but that also is not working and giving this error:
-bash-3.2# java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)
-bash-3.2# uname -a
Linux ip-10-130-225-20 2.6.16.33-xenU #2 SMP Wed Aug 15 17:27:36 SAST 2007 x86_64 x86_64 x86_64 GNU/Linux
-bash-3.2# sudo /usr/java/jdk1.6.0_24/bin/jstack -F 15668
Attaching to process ID 15668, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 19.1-b02
Deadlock Detection:
No deadlocks found.
Thread 8183: (state = BLOCKED)
Error occurred during stack walking:
sun.jvm.hotspot.debugger.DebuggerException: sun.jvm.hotspot.debugger.DebuggerException: get_thread_regs failed for a lwp
at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$LinuxDebuggerLocalWorkerThread.execute(LinuxDebuggerLocal.java:152)
at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.getThreadIntegerRegisterSet(LinuxDebuggerLocal.java:466)
at sun.jvm.hotspot.debugger.linux.LinuxThread.getContext(LinuxThread.java:65)
at sun.jvm.hotspot.runtime.linux_amd64.LinuxAMD64JavaThreadPDAccess.getCurrentFrameGuess(LinuxAMD64JavaThreadPDAccess.java:92)
at sun.jvm.hotspot.runtime.JavaThread.getCurrentFrameGuess(JavaThread.java:256)
at sun.jvm.hotspot.runtime.JavaThread.getLastJavaVFrameDbg(JavaThread.java:218)
at sun.jvm.hotspot.tools.StackTrace.run(StackTrace.java:76)
at sun.jvm.hotspot.tools.StackTrace.run(StackTrace.java:45)
at sun.jvm.hotspot.tools.JStack.run(JStack.java:60)
at sun.jvm.hotspot.tools.Tool.start(Tool.java:221)
at sun.jvm.hotspot.tools.JStack.main(JStack.java:86)
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.tools.jstack.JStack.runJStackTool(JStack.java:118)
at sun.tools.jstack.JStack.main(JStack.java:84)
Caused by: sun.jvm.hotspot.debugger.DebuggerException: get_thread_regs failed for a lwp
at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.getThreadIntegerRegisterSet0(Native Method)
This bug seems to be open with java team.
Any other suggestion to intelligently take and analyze thread dumps? Or script to parse huge catalina.out and get just thread dumps out of it?
Checkout this article about scheduling thread dumps. I think it is exactly what you are trying to do.
Another option could be JMX - ThreadMXBean. This was discussed at SO question How do I create a thread dump via JMX?
One quick way I figured out was (mis)using javamelody. We use it to monitor various aspects of application and it also provides visual & usual ways to look at current threads so I wrote small shell script to hit "http://IP:PORT/SERVICE/monitoring?part=threadsDump" every minute and dump response in a file. If response contains any blocked thread script will take thread dumps every 5 seconds. This helps upto some extent but when problem worsens and server stalls, javamelody also stop responding.
Related
Long story short, some coworkers are running a pretty old setup(oc4j jdk1.5.6 in x86_64) with an application which happens to be mission critical. They recently have tried to deploy a new version of the application, but as soon as they do the java process(es) throw a core dump and die.
The problem is, the core dumps seem to be fine, gdb can open them, but jmap and other tools refuse to process them:
# /usr/java/jdk1.5.0_06/bin/jmap /usr/java/jdk1.5.0_06/bin/java core
Attaching to core core from executable /usr/java/jdk1.5.0_06/bin/java, please wait...
Error attaching to core file: Can't attach to the core file
And newer versions throw a exception:
# jdk1.6.0_45/bin/jmap /usr/java/jdk1.5.0_06/bin/java core
Attaching to core core from executable /usr/java/jdk1.5.0_06/bin/java, please wait...
Exception in thread "main" java.lang.reflect.InvocationTargetException
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.tools.jmap.JMap.runTool(JMap.java:179)
at sun.tools.jmap.JMap.main(JMap.java:110)
Caused by: sun.jvm.hotspot.runtime.VMVersionMismatchException: Supported versions are 20.45-b01. Target VM is 1.5.0_06-b05
at sun.jvm.hotspot.runtime.VM.checkVMVersion(VM.java:224)
at sun.jvm.hotspot.runtime.VM.<init>(VM.java:287)
at sun.jvm.hotspot.runtime.VM.initialize(VM.java:357)
at sun.jvm.hotspot.bugspot.BugSpotAgent.setupVM(BugSpotAgent.java:594)
at sun.jvm.hotspot.bugspot.BugSpotAgent.go(BugSpotAgent.java:494)
at sun.jvm.hotspot.bugspot.BugSpotAgent.attach(BugSpotAgent.java:348)
at sun.jvm.hotspot.tools.Tool.start(Tool.java:169)
at sun.jvm.hotspot.tools.PMap.main(PMap.java:67)
... 6 more
gdb offers little information without symbols:
Reading symbols from /usr/java/jdk1.5.0_06/bin/java...(no debugging symbols found)...done.
[New Thread 9841]
[New Thread 31442]
[New Thread 31441]
...
Core was generated by `/usr/java/jdk1.5.0_06/bin/java -server -XX:+UseConcMarkSweepGC -XX:MaxHeapFreeR'.
Program terminated with signal 6, Aborted.
#0 0x0000003bbf030285 in ?? ()
(gdb) bt
#0 0x0000003bbf030285 in ?? ()
#1 0x0000003bbf031d30 in ?? ()
#2 0x0000000000000000 in ?? ()
The only valuable information I've gathered from the core is that most threads
are blocked(I'm far from being a gdb guru):
35 Thread 10093 0x0000003bbfc0b1c0 in pthread_cond_timedwait##GLIBC_2.3.2 ()
from /lib64/libpthread.so.0
34 Thread 10097 0x0000003bbfc0b1c0 in pthread_cond_timedwait##GLIBC_2.3.2 ()
from /lib64/libpthread.so.0
33 Thread 10099 0x0000003bbfc0b1c0 in pthread_cond_timedwait##GLIBC_2.3.2 ()
from /lib64/libpthread.so.0
Besides, I don't know if it's really relevant. The app is almost always heavily loaded, and my bet is that there were some lock contention already but since it's another's team app my knowledge about it it's pretty shallow.
I guess this is a long shot, but is there something that we can do to get a java thread dump or something like that? Do Sun used to offer debuginfo of the jdk as I guess is avalaible now with openjdk?
Thanks in advance.
UPDATE: The other team has resolved the issue without getting info from the core dump, just by trial and error after successfully replicating the problem in a test system. I'm still intrigued about the thing: how to debug an ancient java core dump which jmap can't process, it might be valuable info for the future, althought it seems is that there is no solution to that problem. Probably the JVM memory got corrupted and that's why jmap can't process it.
You can add the following JVM option when starting your application, that will allow you to run any command you specify if a fatal JVM error occurs:
-XX:OnError="<cmd args>"
For instance, you could run a command (or a script) that will perform certain actions like get a heap or thread dump.
Jmap and other JVM utilities are extremely version sensitive. From your error, it is self explanatory that hopefully the same jvm is not used in your case.
Java VisualVM can load core dumps directly. But you must use the same jvm that created the core file.
Resource Link:
https://stackoverflow.com/a/9981498/2293534
Suggestion#1:
kjkoster has given a solution here in this tutorial.
You need to use the jmap that comes with the JVM. From your error
message I gather that you are using a different version of jmap than
of the JVM.
Please check what JVMs are installed on your machine and ensure than
when you run jmap, you use the right version.
To solve such issues I never rely on path. Instead I set JAVA_HOME to
be the one that the JVM uses and then invoke both the JVM and jmap
like so:
Code:
$ JAVA_HOME=/usr/local/jdk1.6.0
$ export JAVA_HOME
$ ${JAVA_HOME}/bin/java ...
...
$ ${JAVA_HOME}/bin/jmap ...
Hope this helps.
Suggestion#2:
It is a full solution step by step is given by Chamilad. Hope it will clarify your root cause and solution procedure.
Almost every Java developer knows about jmap and jstack tools that come with the JDK. These provide functionality to extract heap and thread information of a running JVM instance. Easy.
What if there’s a running JVM that has produced a deadlock and you want to take a thread dump while the process is running? You go in and run the following.
jstack pid >> thread_dump.txt
Turns out the system doesn’t know what jstack is. You don’t panic, but you get a tiny sensation at the back of your head saying you’re not leaving early this Friday.
What has happened is the running JVM is based on a JRE and not a JDK. The JRE is a minimal runtime that doesn’t pack the monitoring and analysis tools that the JDK packs.
So what are our options here?
Stop the process. Download JDK, start the process again on top of
JDK and hope the deadlock happens again. Nope.
Start JVisualVM on your laptop and hope the process has JMX enabled. Nope.
tools.jar TO THE RESCUE!
Functionalities such as jstack are implemented in the tools.jar file which is packed inside <JDK_HOME>/lib folder. We can use this to invoke the JStack class and get a thread dump of the running process.
So we march on to download and extract the JDK, and then to run the following.
java -classpath <JDK_HOME>/lib/tools.jar sun.tools.jstack.JStack <pid> >> thread_dump.txt
..and come across the following error.
Exception in thread "main" java.lang.UnsatisfiedLinkError: no attach in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
at sun.tools.attach.LinuxVirtualMachine.<clinit>(LinuxVirtualMachine.java:342)
at sun.tools.attach.LinuxAttachProvider.attachVirtualMachine(LinuxAttachProvider.java:63)
at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:208)
at sun.tools.jstack.JStack.runThreadDump(JStack.java:163)
at sun.tools.jstack.JStack.main(JStack.java:116)
Darn it! Spoiled again!
How do we solve this? The above error is caused when the process can’t find libattach.so file which is related to the Dynamic Attach function related to JStack. Setting the following environment variable will help the JVM to find the libattach.so file.
export LD_LIBRARY_PATH=<JDK_HOME>/jre/lib/amd64/
Now let’s run JStack again, this time with results!
java -classpath <JDK_HOME>/lib/tools.jar sun.tools.jstack.JStack <pid> >> thread_dump.txt
Now that we have the thread dump, we move on to the heap dump. The tool we normally use is jmap but that too is not available on the JRE. So what? We can use the binary in the JDK’s bin directory right? right?
root#snowflake1 latest]# <JDK_HOME>/bin/jmap -heap <pid>
Attaching to process ID <pid>, please wait…
Error attaching to process: sun.jvm.hotspot.runtime.VMVersionMismatchException: Supported versions are 25.102-b14. Target VM is 25.91-b14
sun.jvm.hotspot.debugger.DebuggerException: sun.jvm.hotspot.runtime.VMVersionMismatchException: Supported versions are 25.102-b14. Target VM is 25.91-b14
at sun.jvm.hotspot.HotSpotAgent.setupVM(HotSpotAgent.java:435)
at sun.jvm.hotspot.HotSpotAgent.go(HotSpotAgent.java:305)
at sun.jvm.hotspot.HotSpotAgent.attach(HotSpotAgent.java:140)
at sun.jvm.hotspot.tools.Tool.start(Tool.java:185)
at sun.jvm.hotspot.tools.Tool.execute(Tool.java:118)
at sun.jvm.hotspot.tools.HeapSummary.main(HeapSummary.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.tools.jmap.JMap.runTool(JMap.java:201)
at sun.tools.jmap.JMap.main(JMap.java:130)
Caused by: sun.jvm.hotspot.runtime.VMVersionMismatchException: Supported versions are 25.102-b14. Target VM is 25.91-b14
at sun.jvm.hotspot.runtime.VM.checkVMVersion(VM.java:227)
at sun.jvm.hotspot.runtime.VM.<init>(VM.java:294)
at sun.jvm.hotspot.runtime.VM.initialize(VM.java:370)
at sun.jvm.hotspot.HotSpotAgent.setupVM(HotSpotAgent.java:431)
… 11 more
Nope! Unless you match the JDK version with the exact version the JRE is at you get the above issue (which is pretty self-explanatory). So we download the JDK of the JRE of on top our process is running and run jmap again.
<JDK_HOME>/bin/jmap -dump:file=heap_dump.hprof <pid>
Resource Link:
Extracting memory and thread dumps from a running JRE based JVM
jmap is not going to help you debug a core dump. The JVM dumps core when either it has a bug or you have JNI code with a problem. Organizations with mission-critical applications should, sadly, see upgrading from unsupported versions of the JVM as mission-critical, or be prepared to pay Oracle a fortune for help.
We have Jenkins setup for running jobs for a project our team is currently working on but we are having problems with the jobs crashing constantly due to an OutOfMemory.
The Jenkins environment is running on a virtual machine. The machine it is on has fairly decent specs and doesn't have to many VMs on it. Our SBT jobs run in a separate jobs list which has 8GB of RAM available.
Project build.properties sbt.version=0.13.9
Jenkins ver. 2.6
We are executing the following command for the job:
/usr/java/default/bin/java -Xmx2G -XX:+CMSClassUnloadingEnabled -XX:MaxMetaspaceSize=2G -Dsbt.override.build.repos=true -Dsbt.log.noformat=true -jar /usr/local/sbt/default/bin/sbt-launch.jar compile test:compile test universal:publish
Which produces the following throughout the log:
Exception in thread "Thread-40" java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2626)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1321)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
at org.scalatest.tools.Framework$ScalaTestRunner$Skeleton$1$React.react(Framework.scala:945)
at org.scalatest.tools.Framework$ScalaTestRunner$Skeleton$1.run(Framework.scala:934)
at java.lang.Thread.run(Thread.java:745)
Exception in thread "Thread-29" java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:209)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.net.SocketInputStream.read(SocketInputStream.java:223)
at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2321)
at java.io.ObjectInputStream$BlockDataInputStream.peek(ObjectInputStream.java:2614)
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2624)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1321)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
at sbt.React.react(ForkTests.scala:114)
at sbt.ForkTests$$anonfun$mainTestTask$1$Acceptor$2$.run(ForkTests.scala:74)
at java.lang.Thread.run(Thread.java:745)
The dump file the job produces here (pastebin.com/EM3qva5C)
We have tried different variations of the java args but all have come to the same result so we are wondering if there is something else wrong/what we need to change to prevent the builds from failing?
Your tests are working in a forked JVM, so you have to provide more memory to them.
Add the following line to build.sbt:
javaOptions ++= Seq("-Xmx1G")
I am trying to Install Jprofiler agent of Centos 7 64 bit with Java 8 and Tomcat 8
root#ads [/opt/jprofiler9]# jpenable
Connecting to org.apache.catalina.startup.Bootstrap start [23360] ...
Please select the profiling mode:
GUI mode (attach with JProfiler GUI) [1, Enter]
Offline mode (use config file to set profiling settings) [2]
1
Please enter a profiling port
[59687]
8849
ERROR: Attaching is not supported: Unable to open socket file: target process not responding or HotSpot VM not loaded
com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file: target process not responding or HotSpot VM not loaded
at sun.tools.attach.LinuxVirtualMachine.<init>(LinuxVirtualMachine.java:100)
at sun.tools.attach.LinuxAttachProvider.attachVirtualMachine(LinuxAttachProvider.java:63)
at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:195)
at com.jprofiler.a.d.b(ejt:292)
at com.jprofiler.a.d.a(ejt:279)
at com.jprofiler.a.d.a(ejt:249)
at com.jprofiler.cli.EnableApplication.a(ejt:132)
at com.jprofiler.cli.EnableApplication.h(ejt:95)
at com.jprofiler.cli.b.a(ejt:26)
at com.jprofiler.cli.EnableApplication.main(ejt:272)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.exe4j.runtime.LauncherEngine.launch(LauncherEngine.java:65)
at com.install4j.runtime.launcher.UnixLauncher.main(UnixLauncher.java:57)
In that case you cannot use jpenable, but you have to use jpintegrate to modify the start script of the profiled application and add the -agentpath parameter that loads the profiling agent at startup.
Are you using sudo to run jpenable ?
Dont use sudo to start jpenable as well as the java process.
I have a problem with starting any java applications. For example just a simple command:
java -version
prints:
Error occurred during initialization of VM
java.lang.ClassFormatError: Unknown constant tag 223 in class file java/util/concurrent/locks/Lock
at java.util.concurrent.ConcurrentHashMap.<clinit>(ConcurrentHashMap.java:1597)
at sun.util.locale.LocaleObjectCache.<init>(LocaleObjectCache.java:48)
at sun.util.locale.LocaleObjectCache.<init>(LocaleObjectCache.java:44)
at java.util.Locale$Cache.<init>(Locale.java:676)
at java.util.Locale$Cache.<init>(Locale.java:675)
at java.util.Locale.<clinit>(Locale.java:411)
at java.lang.String.toLowerCase(String.java:2524)
at java.net.URL.<init>(URL.java:377)
at java.net.URL.<init>(URL.java:302)
at java.net.URL.<init>(URL.java:325)
at sun.net.www.ParseUtil.fileToEncodedURL(ParseUtil.java:272)
at sun.misc.Launcher.getFileURL(Launcher.java:460)
at sun.misc.Launcher$ExtClassLoader.getExtURLs(Launcher.java:192)
at sun.misc.Launcher$ExtClassLoader.<init>(Launcher.java:164)
at sun.misc.Launcher$ExtClassLoader$1.run(Launcher.java:148)
at sun.misc.Launcher$ExtClassLoader$1.run(Launcher.java:142)
at java.security.AccessController.doPrivileged(Native Method)
at sun.misc.Launcher$ExtClassLoader.getExtClassLoader(Launcher.java:141)
at sun.misc.Launcher.<init>(Launcher.java:71)
at sun.misc.Launcher.<clinit>(Launcher.java:57)
at java.lang.ClassLoader.initSystemClassLoader(ClassLoader.java:1489)
at java.lang.ClassLoader.getSystemClassLoader(ClassLoader.java:1474)
This behavior started after I installed Liferay, so I think it might be that some limit of concurrent locks have been exceeded, but I could not google any information on this.
The computer restart solved it, but I still wonder what really caused the behavior and how could it be solved without restarting.
The API docs at http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Lock.html didn't help neither.
About the system:
sudo update-alternatives --config java
There are 2 choices for the alternative java (providing /usr/bin/java).
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/lib/jvm/java-7-oracle/jre/bin/java 1075 auto mode
1 /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java 1071 manual mode
2 /usr/lib/jvm/java-7-oracle/jre/bin/java 1075 manual mode
When I start tomcat 6 it freezes in certain point of the startup and stays there forever (I've waited 3 hours and nothing happened - not even an out of memory error). I don't have any clue of what could cause a behavior like that.
I'm runnig tomcat with Jira and Confluence, and the problem seem to be when tomcat tries to load confluence:
******************************************************************************************************
JIRA 3.13.3 build: 344 (Enterprise Edition) started. You can now access JIRA through your web browser.
******************************************************************************************************
2009-06-02 19:38:21,272 JiraQuartzScheduler_Worker-1 INFO [jira.action.admin.DataExport] Export took 387ms
2009-06-02 19:38:21,291 JiraQuartzScheduler_Worker-1 INFO [jira.action.admin.DataExport] Wrote 392 entities to export
2009-06-02 19:38:21,606 INFO [main] [com.atlassian.confluence.lifecycle] contextInitialized Starting Confluence 2.10.3 (build #1519)
2009-06-02 19:38:21,711 INFO [main] [beans.factory.xml.XmlBeanDefinitionReader] loadBeanDefinitions Loading XML bean definitions from class path resource [bootstrapContext.xml]
2009-06-02 19:38:22,236 INFO [main] [beans.factory.xml.XmlBeanDefinitionReader] loadBeanDefinitions Loading XML bean definitions from class path resource [setupContext.xml]
After this line above nothing more happens.
I thought it could be a problem with permGem or something like that, so to avoid permGem limitations, I configured catalina.sh with:
CATALINA_OPTS="$CATALINA_OPTS -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true"
JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1536m -Xmx1536m -XX:PermSize=256m -XX:MaxPermSize=640m -XX:+DisableExplicitGC"
I incresed a lot jvm's space to see if it works, but it didn't help.
Tomcat version: 6.0.18
Jira version: 3.13.3
Confluence Version: 2.10.3
So, anyone have already had this problem before?
Could it be a memory(RAM) problem?
A problem with Spring and Tomcat6?
Or any other kind of problem?
Do you have any errors in your log?
Have you checked if confluence is maybe waiting for the database or network?
Get a thread dump for the application and check for threads which are BLOCKED, WAITING or TIMED_WAITING.
Also beware of threads in RUNNABLE but doing network I/O, e.g InputStream.read().
I checked my database, it was not working at all, but that was not the problem that was making my tomcat freeze.
I had a lack of RAM issue. In that place where tomcat got stuck there was a memory peak to load a lot of stuff from confluence.
I am using a virtual machine(VMware) to run my confluence, jira and svn inside a server with 3 other virtual machines.
To solve the problem I had to increase the memory(RAM) my virtual machine could use, from 2Gb to 4Gb.
please check whether $CATALINA_BASE/common/lib/javaee.jar exists