I'm currently writing a Java application that needs to look at how "heavily loaded" the machine it's running on is. On *nix, load average divided by number of processors fits the bill perfectly, and we retrieve load average with ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage(). Unfortunately, this returns -1 on Windows, as the call is apparently too "expensive" to be called frequently. What's the easiest way to retrieve similar Windows metrics such as the processor queue length or CPU utilisation, either in pure Java or via JNI?
You can retrieve the CPU utilization on Windows using WMI. Some code and documentation for accessing WMI from Java appears to be available here.
Try using the free Hyper SIGAR API. It is a cross platform API for calling system information. It uses JNI for Windows/Linux/Unix/Mac/etc.
http://www.hyperic.com/products/sigar
I wrote a JNLP task manager/information monitor with it and it's a decent API.
http://www.goliathdesigns.com/2009/12/sixth-post/
Source code:
http://sourceforge.net/projects/sysinfomonitor/
You can also perfom this task using Eclipse SWT if you are running on an win32 environment:
http://dentrassi.de/2011/02/04/access-to-wmi-in-java-using-eclipse-swt-ole-integration/
Related
As I indicated in another post, I'm having trouble with some SPIN constructors taking an excessive amount of time to execute quite limited data. I thought I'd take a different approach and see if I can profile the execution of the constructors to gain insight into where specifically they are spending excessive time.
How do I go about profiling the execution of constructors under RDF4J Server? I'm instantiating via SPARQL update (INSERT DATA) queries. Here's the System Information on RDF4J workbench:
I've attempted to profile the Tomcat server under which the RDF4J Server runs using jvisualvm.exe, but I have not gained much insight. Ideally, I'd like to get down to the class/method level within RDF4J so that I can post a more detailed request for help on my slow execution problem or perhaps fix my queries to be more efficient themselves.
So here's the version of Java Visual VM:
RDF4J is running under Apache Tomcat 8.5.5:
I can see overview information on Tomcat:
I can also see the monitor tab and threads:
HOWEVER, what I really want to see is the profiler so that I can see where my slow queries are spending so much time. That hangs on Calibration since I don't have the profiler calibrated for Java 1.8.
This attempting to connect box will persist indefinitely. Canceling it leads to the Performing Calibration message which doesn't actually do anything and is a dead-end hang requiring the Java VisualVM to be killed.
After killing the Java Visual VM and restarting and looking at Options-->Profiling-->Calibration Data, I see that only Java 7 has calibration data.
I have tried switching Tomcat over to running on Java 7, and that did work:
The profiler did come up with Tomcat:
However, when I tried to access the RDF4J workbench while Tomcat ran on Java 7, I could not get the workbench running:
So, I'm still stuck. It would appear that RDF4J requires Tomcat running under Java 1.8, not 1.7. I can't profile under Java 1.8.
I have seen other posts on this problem with Java VisualVM, but the one applicable solution seems to be to bring everything up in a development environment (e.g. Eclipse) and dynamically invoke the profiler at a debugger breakpoint once the target code is running under Java 1.8. I'm not set up to do that with Tomcat and RDF4J and would need pointers. My intention was not to become a Tomcat or RDF4J contributer (because my tasking doesn't allow that... I wouldn't be paid for the time) but rather to get a specific handle on what's taking so long for my SPIN constructor(s) in terms of RDF4J server classes and then ask for help from the RDF4J developer community on gitub.
Can Java VisualVM calibration be bypassed? Could I load a calibration file or directory somewhere for Java VisualVM to use instead of trying to measure calibration data which fails? I'm only interested in the relative CPU loading of classes, not absolute metrics, and I don't need to compare to measurements on other machines.
Thanks.
Is there a gprof-like profiler for Java that can be run from the terminal in Linux?
All tools I have found are GUI programs and I need run it from the terminal.
The JVM has a built-in profiler called HPROF. You can enable it on the command line like this:
java -agentlib:hprof=file=hprof.txt,cpu=samples MyClass
This will dump profile information out to a text file when the program finishes. In addition to profiling CPU usage, it can also track heap usage.
The open-source tool jvmtop contains a terminal profiler and might be worth a look:
JvmTop 0.7.0 alpha - 15:16:34, amd64, 8 cpus, Linux 2.6.32-27, load avg 0.41
http://code.google.com/p/jvmtop
Profiling PID 24015: org.apache.catalina.startup.Bootstrap
36.16% ( 57.57s) hudson.model.AbstractBuild.calcChangeSet()
30.36% ( 48.33s) hudson.scm.SubversionChangeLogParser.parse()
7.14% ( 11.37s) org.kohsuke.stapler.jelly.JellyClassTearOff.parseScript()
6.25% ( 9.95s) net.sf.json.JSONObject.write()
3.13% ( 4.98s) ....kohsuke.stapler.jelly.CustomTagLibrary.loadJellyScri()
JXInsight/OpenCore has term/shell reporting plugins (top, queues, stacks,...) that will output its metering and metrics data at regular intervals. It is also possible to access this information using the Open API which allows inspection of the model in real-time within the JVM or offline using a snapshot file handle. Both are supported via Plugin API which it how the top, queues,... ones work.
http://www.jinspired.com/products/opencore (commercial)
Is there a technical reason you can't use a GUI? Is it just a preference driven by a workflow habit? If not then you can always try out our FREE JXInsight/Opus Java Edition - a highly efficient and scalable code level latency performance measurement solution for rapidly identifying hotspots within Java and JRuby applications.
http://www.jinspired.com/products/opus
Note: I am the product architect of both products.
I use jconsole for that. http://docs.oracle.com/javase/6/docs/technotes/tools/share/jconsole.html
If you want it for profiling and monitoring. You can use Jvisualvm.
from App site:
DESCRIPTION
Java VisualVM is an intuitive graphical user interface that provides detailed information about Java technology-based applications (Java applications) while they are running on a given Java Virtual Machine (JVM*). The name Java VisualVM comes from the fact that Java VisualVM provides information about the JVM software visually.
Java VisualVM combines several monitoring, troubleshooting, and profiling utilities into a single tool. For example, most of the functionality offered by the standalone tools jmap, jinfo, jstat and jstack have been integrated into Java VisualVM. Other functionalities, such as some of those offered by the JConsole tool, can be added as optional plug-ins.
EDIT:
As you want a terminal approach.Refer this link Triggering a Javadump.
It describes creation of java dump.
I currently work in a Weblogic Java EE project, where from time to time the application executes a Perl script to do some batch jobs. In the application the script is getting invoked as
Process p = Runtime.getRuntime().exec(cmdString);
Though it is a dangerous way to run, but it was working properly until we had a requirement to execute the script synchronously under a for loop. After a couple of run we are getting
java.io.IOException: Not enough space as probably OS is running out of virtual memory while exec-ing under a for loop. As a result we are not able to run the script at all in the server.
I am desperately looking for a safer and better way to run the Perl script, where we don't need to fork the parent process, or at-least not to eat-up all swap space!
The spec is as follows:
Appserver - Weblogic 9.52
JDK - 1.5
OS - SunOS 5.10
Sun-Fire-T200
I've had something similar on a couple of occasions. Since the child process is a fork of the (very large parent it can see all of it shares all it's memory (using copy on write). What i discovered was that the kernel needs to be able to ensure that it could copy all of the memory pages before forking the child, on a 32bit OS you run out of virtual head run really fast.
Possible solutions:
Use a 64Bit OS and JVM, pushes the issue down the road so far it doesn't matter
Host your script in another process (like HTTPD) and poke it using a HTTP request to invoke it
Create a perl-server, which reads perl scripts via network and executes them one by one.
If you want to keep your code unchanged and have enough disk free space, you can just add a sufficiently large swap area to your OS.
Assuming you need 10 GB, here is how you do it with UFS:
mkfile 10g /export/home/10g-swap
swap -a /export/home/10g-swap
echo "/export/home/10g-swap - - swap - no -" >> /etc/vfstab
If you use ZFS, that would be:
zfs create -V 10gb rpool/swap1
swap -a /dev/zvol/dsk/rpool/swap1
Don't worry about that large a swap, this won't have any performance impact as the swap will only be used for virtual memory reservation, not pagination.
Otherwise, as already suggested in previous replies, one way to avoid the virtual memory issue you experience would be to use a helper program, i.e. a small service that your contact through a network socket (or a higher level protocol like ssh) and that executes the perl script "remotely".
Note that the issue has nothing to do with a 32-bit or 64-bit JVM, it is just Solaris doesn't overcommit memory and this is by design.
How can i get cpu usage of any application from java program using wmi query.I use jacob api for accessing wmi.
Please take a look here: How to know the CPU and memory usage of a process with WMI?
Seems like
Select Name,PercentProcessorTime from Win32_PerfFormattedData_PerfProc_Process
should work for you.
I use C# to program and use ReadProcessMemory to read the memory of other processes running on the system. However, I'm unsure how to read the memory of a java applet that is running inside a browser? Has anyone tackled this before?
Thanks.
Since 6u10 the default Java PlugIn runs outside of the browser process(es). The process should be readily identifiable as a Java executable with PlugIn classes added to the bootstrap class path.
If the JVM is executing as part of the browser process, I suspect you won't be able to do this easily. The closest you'll be able to get is to measure the browser memory consumption.
However you could measure the memory consumption of the standalone applet viewer whilst running your applet, and then perhaps derive the applet memory consumption from that.