Location of Java dump heap file when using jconsole? - java

Well this is embarrassing ...
I'm starting to play with the Eclipse Memory Analyzer to look for Java memory leaks on a Windows box. Step 1 is to obtain a heap dump file. To do this I start my Java (javaw.exe) process from within Eclipse and connect to it with jconsole. Then on the jconsole MBeans tab I click the dumpHeap button. The first time I did this, I saw a pop-up saying it had created the heap dump file, but not giving its name or location. Now whenever I do a dumpHeap again while connected to a different javaw.exe process, jconsole says:
Problem invoking dumpHeap : java.io.IOException: File exists
and of course doesn't give its name or path. Where could it be?
I've searched my C: drive (using cygwin command line tools) for files containing "hprof" or "java_pid" or "heapdump" and didn't find anything plausible. I've even used the Windows search to look for all files in my Eclipse workspace that have changed in the last day.
I'm using the Sun Java 1.6 JVM, and don't have -XX:HeapDumpPath set.
Update (28 April 2010): My original heap file location must have been determined by jconsole, the tool I triggered the heap dump from. The JVM's heap dump location must apply only to heap dumps it triggers (eg, on an OutOfMemoryException).
Matt B's suggestion to use jvisualvm nicely solves my problem by pointing me to a far more useful replacement for the old jconsole. It has a nice memory profiler that shows which types of objects are most numerous and hold the most memory. And it has a monitor that shows actual memory use over time. When you ask it for a heap dump, it tells you the file name even! The Eclipse Memory Analyzer gives you full details.

Try jvisualvm, it has a much better interface.
Note that starting with JDK version 6 update 7 or greater, Java VisualVM is bundled with JDK. See here.

According to the docs for the Sun Java SE6 JVM:
By default the heap dump is created in
a file called java_pid<pid>.hprof in the
working directory of the VM
In Eclipse, the working directory is defined on the "Arguments" tab of the "Run Configurations" dialog. The default value is the same directory as the class that you are running.

why don't you set the first parameter for dumpHeap(String,boolean) when you try to invoke dumpHeap() from jconsole? it's the generated heapdump file's location and filename.

You could always use ProcessMonitor to see where it's trying to write to :) Done this myself in the past.

I found the dumped file into the same folder where the .bat file whic launch my java application is placed. (I'm using windows 8.1, java 7)
In my case jboss, /jboss-as/bin/ folder.
To find it I searched * files, with today creation date and more than 200MB.

Related

Heap dump on JRE 6 (Windows) without JDK

Is there a way to create a heap dump on a remote machine without JDK installed?
I can't change the installation / settings and it's running on Windows.
So I have pnly access to commandline tools.
Problem is that a Java app on a remote machine freezes (no out of memory exception so -XX:-HeapDumpOnOutOfMemoryError is useless) and we need to create a dump.
-XX:+HeapDumpOnCtrlBreak
is no option too, because it's not supported anymore on JDK6+.
JMX is not allowed due to security reasons.
Any Ideas? Thank you for your help!
Edit:
Windows
No JDK
No JMX
I think I solved the problem.
You have to "patch" your JRE with some files of the JDK (the same version of course - if you are running jre6uXX you need the corresponding files from jdk6uXX )
Copy the following files:
\JDK6uXX\bin\attach.dll --> %JAVAJRE_HOME%\bin\
\JDK6uXX\bin\jmap.exe --> %JAVAJRE_HOME%\bin\
\JDK6uXX\lib\tools.jar --> %JAVAJRE_HOME%\lib\
No files are overwritten, JRE shouldn't be affected by this.
Now you can use jmap just fine to take dumps ;-)
I appreciate your help! Bye
The simplest solution is to use jmap -dump:liv,format=b,file=app.dump on the command line. You can use jps -lvm to find the process id.
An alternative is to connect to it to jvisualvm This will take the dump and analyse it for you. You can also use this tool to read a dump written by jmap so you may end up using it anyway.
Where jvisualvm struggles is for large heap dumps i.e. more than about half you main memory size. I have found using YourKit to handle larger dumps and also give more useful information. An evaluation license might be all you need to diagnose this.
jmx is not allowed due to security reasons
In that case, you can't do this remotely, unless you use YourKit or some other commercial profiler.
You have start your application with jmx console enabled in a port to debug your application. Execute jconsole and connect to the port which you have enabled for debugging. You can also use of jmap to collect heapdump.
JProfiler has a command line utility bin/jpdump that can take an HPROF heap dump. There is no need to install JDK. There is also no need to run the GUI installer of JProfiler, just extract the ZIP distribution and execute jpdump on the command line.
Disclaimer: My company develops JProfiler.
Update 2016-06-23
As of JProfiler 9.2, jpdump and jpenable run with Java 6 as well.
You could use jvisualvm, just enable jmx port and connect to your application, then you will be able to generate a heap file.
You can do that by adding the following parameters:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.port=8484
-Dcom.sun.management.jmxremote.ssl=false
Then You need to add your tomcat process manually, So right click on you localhost node -> Add JMX Connection -> type your port -> OK.
Your tomcat process will be listed in under localhost node.
jmap -dump:format=b,file=snapshot.jmap
process-pid
Regardless of how the Java VM was started, the jmap tool will produce a head dump snapshot, in the above example in a file called snapshot.jmap. The jmap output files should contain all the primitive data, but will not include any stack traces showing where the objects have been created.

Why won't the VisualVM Profiler profile my application?

I've created a simple 1 file java application that iterates through a loop, calls some functions, allocates some memory, adds some numbers, etc. I run that application via eclipse's Run As->Java Application.
The running application shows up in Java VisualVM under Local.
I double click on that application and go to the Profiler tab.
The default settings are:
Start profiling from classes: my.main.package.**
Do not profile classes: java.*, javax.*,
sun.*, sunw.*, com.sun.*
I click on CPU. The CPU and Memory buttons gray out. Nothing happens.
The Status says profiling inactive.
When my application terminates the Status says application terminated.
What am I doing wrong here? Are there some settings I need to tweak? Do I need to set a VM flag when I launch my application?
I had the same issue after java 1.7.0_45 update. I had to delete the following folder:
C:\users\'username'\AppData\Local\Temp\hsperfdata_'username'
After doing so, everything works like a charm.
I'd guess the issue relates to the application being started from within Eclipse, this is because JVisualVM expects to find data in the java.io.tmpdir directory (usually C:\Users\[your username]\AppData\Local\Temp\hsperfdata_[your username] on a Windows system).
I assume rather than in the normal location where JPS, JVisualVM etc. expects it, Eclipse puts the data in it's own temp folder?
If so, try invoking JVisualVM using jvisualvm -J-Djava.io.tmpdir=[Eclipse's temp directory] to explicitly tell it where that data is.
If you can't find the hsperfdata_$USER folder, try just running your application outside Eclipse in the usual command line Java way.
Also note that there was a bug affecting the temp folder (case sensitivity) introduced around 1.6.0_23, so maybe you'd benefit by updating to a more recent Java 6 (or 7) build?
Mikaveli, Kuba and Somaiah Kumbera have provided great solutions. Just adding what I have done to make things work.
I first checked the location C:\users\'username'\AppData\Local\Temp\hsperfdata_'username' There was no file named with the process ID of my program running inside eclipse.
I simply stopped the program and added the following parameter to the Run Configurations of the program (Run Configurations -> Arguments -> VM Arguments)
-Djava.io.tmpdir=C:\users\'username'\AppData\Local\Temp\hsperfdata_'username'
I started the program again. Still could not profile it. But now I have a file created for the process at the given temp directory.
Then, a simple restart of VisualVM did the trick.
I had the same issue, but with the following symptoms:
I started jetty, with the work directory in
C:\Users\t852124\AppData\Local\Temp
Jetty was creating the hsperfdata_ directory but not setting a processID in it
So when I started visualVM, it could not get any java process info.
I solved this by starting jetty with the -Djava.io.tmpdir=C:/temp/java option.
Now when I started jetty, the process ID was created as a file in the hsperfdata_ directory.
So when I started visualVM, it was able to see my local java process
I had the same problem and running VisualVM with elevated privileges (admin rights) solved the issue.
On Linux with VisualVM 1.3.3 I have to remove local settings of application in ~/.visualvm/1.3.3/ to enable CPU Profiler and CPU Sampler.
Also note that /usr/bin/jvisualvm contains hardcoded path to OpenJDK (set with jdkhome variable), which seems to cause a lot of issues, comparing to running to Oracle JDK 1.7.
Also note that if your application is using a recent non-Oracle JVM, you may need to download the "bleeding edge" VisualVM from github.
For example, the VisualVM bundled with JDK 1.8.0.111 doesn't seem to work with the IBM 1.8 JVM. Possibly the IBM JVM was simply released after the Oracle 1.8 JVM, so including the necessary changes wasn't possible at that time.

Help setting up Java VM size

Well I am very new to Java and can't understand how am I supposed to set the virtual machine's size. I've built a small web applet that displays images. Sometimes the images can be pretty large, when this happens I get:
*Exception in thread "Image Fetcher 0" java.lang.OutOfMemoryError: Java heap space*
I've been trying to follow different instructions that I found on the Internet and have finally created this shortcut to Eclipse with the following command-line:
"C:\Documents and Settings\Dror Well\Desktop\temp\Eclipse\eclipse\eclipse\eclipse.exe"
-vmargs -vm "C:\Program Files\Java\jdk1.6.0_14\bin"
\"C:\Program Files\Java\jre6\bin\javaw.exe" -Xms256m -Xmx1024m
What am I missing? How should this be done?
In that line you have set the VM args to the Java process that Eclipse runs in. What you need to do for your application is to set the -Xmx512m (or however big you want it to be) for the application that you are running. You can do this from the Run dialog.
From the Run menu, choose 'Open Run Dialog'. In there, you should see on the left side a list of programs. If you have run it once already, yours should be listed in the Java Applications node. Select it and on the right panel, go to the Arguments tab. There will be a VM Arguments text box. Enter your -Xmx arg there.
The parameters should be passed to the JVM running your application, not the one running Eclipse. Try looking through the debug settings in Eclipse, there should be some place to put the -Xmx and -Xms parameters.
Since the images can be pretty large, you should look at the following alternatives:
Allocate more memory to the Java executable that will be launched by Eclipse (not Eclipse itself). This can be done via the VM arguments for the runtime configuration that you use to run the application in Eclipse.
Switch to the parallel garbage collector, using the -XX:+UseParallelGC flag for the application (again, this is not for Eclipse). This wont help if you have large objects retained in memory for a long period of time.
For Eclipse you need to update the eclipse.ini file in order to set any JVM properties. Full details on where the file is and how to update it this link.

Can I get Tomcat running as a service to dump heap?

I am attempting to have Tomcat, which is currently running as a service on a Windows 2003 box, dump heap on an OutOfMemoryError.
(Tomcat is running Hudson, which is reporting a heap space problem at the tail end of my build. Running the build manually produces no such error. The Hudson guys need a heap dump to get started.)
As instructed elsewhere, I've told the Apache Service Monitor to configure the JVM it uses to run Tomcat to dump heap when an OutOfMemoryError is encountered by adding the following to the JVM options:
-XX:+HeapDumpOnOutOfMemoryError
Then I run the build again. Sure enough, it reports there was a heap error. I scan the entire disk looking for the default java_pid123.hprof file (where obviously 123 is replaced by the PID of the JVM). No .hprof files exist anywhere.
I am caught in a catch 22: I need the heap dump for the Hudson guys to fix their memory leak, but I can't get the heap dump if I run Hudson under Tomcat.
Is there some special way, when Tomcat is running as a Windows service, to get a heap dump from it on an OutOfMemoryError?
The other thing I've tried is to tell it, on the Startup and Shutdown tabs, to use the "Java" option instead of the "jvm" option. I believe this should tell the Service Manager to attempt to start Tomcat with a Java executable command instead of launching the jvm.dll directly. When I do this, the service won't start.
Surely someone else has had a similar problem?
After finally putting this one to bed, I wanted to answer this for others who might have the same problem.
First, if you install Tomcat on Windows, do not use the .exe installer, even though it is promoted by Apache. It will not let you run Tomcat as anything other than the system account, no matter what you do. It appears that the system account does not have privileges to write .hprof files in the current directory, and no amount of Windows security tweaking appears to make this problem go away.
OK, so you've installed Tomcat from the .zip distribution. Install it as a service using the service.bat script. Make sure it is set to run as a specific user that you created specifically for this purpose. Make sure as well that the folder you want Tomcat to write to in the event of a heap dump is writable by that user.
Edit the service.bat file to include the -XX:+HeapDumpOnOutOfMemoryError and the -XX:HeapDumpPath=C:\whatever options in the correct place (where you can put JVM options). That should do the trick.
Have you tried -XX:HeapDumpPath option?
http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp
I found the following link, which describes how to configure the tomcat service (includes setting the java parameters). Not sure if it applies to the version you are running.
http://tomcat.apache.org/tomcat-5.5-doc/windows-service-howto.html
When java process running as window service you can generate the heapdump using below steps,
Run the command console as Administrator
version of JDK (for jmap command) and JRE (Java app run environment) should be same.
Get the PID no of running window process for that java application from task manager
Execute below command
jmap -dump:file=d:\heapdump\myHeapDump.hprof -F #PID_No#
If got any exception with JDK/JRE 7 try the same with JDK/JRE 8
Actually I faced some issue in jmap with JDK 7, but when i moved to JDK 8, I were able to successfully generate the heap dump using same command
The .hprof files are dumped in the current directory. Exactly what that means for a windows service is anyone's guess, assuming it means anything.
I suggest posting a new question (on http://superuser.com) asking what "current directory" means for a windows service.
From 20 Tips for Using Tomcat in Production
Add the following to your JAVA_OPTS in catalina.sh (or catalina.bat for Windows): -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/j2ee/heapdumps
if you have installed tomcat with .exe you can configure tomcat service to use account other than local system account and you can assign that user rights on directory "c:\whatever" where you are creating your dump file. one thing here to remember tomcat service don't run with account having administrative privileges. so create a simple user in windows(member of user group) and set tomcat services to user this account. and give that user rights on "c:\whatever" directory. This resolves the user directory rights issue but you have to configure tomcat for Memory dumps errors.

OutOfMemory in Eclipse in a Launched process

I have an OutOfMemory (heap size) in eclipse using a third party plugin
The plug in is Adobe Livecycle work bench and during the out of memory the
plugin is retrieving via WS (using Axis) a list of around 70 workflow components
on my server
Here is a extract of my call stack in Eclipse
... at org.eclipse.equinox.launcher.Main.main(Main.java:1144)
Caused by: java.lang.OutOfMemoryError: Java heap space; nested
exception is: java.lang.OutOfMemoryError: Java heap space at
org.apache.axis.message.SOAPFaultBuilder.createFault ...
I am using this eclipse.ini
-showlocation
-vm
C:\bea920\jdk150_04\bin\javaw.exe
-vmargs
-Xms512M
-Xmx1024M
I don't use any commandline options
I have added -Xmx1024m to my only Installed JRE in Java/Installed JREs
It seems to me that :
-eclipse is not OutOfMemory itself
it displays only 300Mo out of 1024Mo used
it continues working properly
-the plugin launch its axis parsing without giving it enough memory
Questions :
- Are my suppositions right ?
- How do I find where and how to give more memory to the process launched by eclipse launcher ?
Have you changed your launched VM arguments from the preferences window? Try this:
Window->Preferences
Java->Installed JREs
(select your jre here)->Edit..
Default VM Arguments: -Xmx1024m (or whatever size you like)
Edit 1: Based on your comments, I see that you've already tried this. I assumed that you did not try it based on the portion of your question that reads "How do I find where and how to give more memory to the process launched by eclipse launcher ?". I guess we all know what happens when we assume!
Have you considered upping the memory to something larger just to see if you can get it to run (and possibly get some more info about what is causing it to crash)? Try -Xmx2048m or larger depending on your available memory.
Can you add some information to your question that gives us an idea of what the plugin does? Is this project a web service? etc..
See if you are passing Xms and Xmx options in the command line that you are running eclipse with. The values there will override the values in the eclipse.ini
I think you need to edit your eclipse.ini file which is located in the
same directory as your eclipse exe file. It will contain the -Xms settings
which you can then change.
I recommend running eclipse with the -clean option to purge any caches and re-read your settings.
Also, I've had success moving the eclipse.ini out of the eclipse directory (so there's no eclipse.ini), running eclipse, exiting, moving the ini file back and running again. I didn't bother to try to understand why that helped.
Add -XX:MaxPermSize=256m
This is yet-another-memory-type in Java.
I was able to find were the problem is
I used Fiddler with eclipse (using proxy settings)
This way I was able to spot that the soap answer was an OutOfMemory
soapenv:Fault
faultcode soapenv:Server.generalException
faultstring java.lang.OutOfMemoryError: Java heap space; nested exception is:
java.lang.OutOfMemoryError: Java heap space
So the problem was on the server
I have now another problem : the server builds an answer which is to big for eclipse
Thank you for your answers

Categories

Resources