I'm kinda confused as to where to start looking to optimize my java-based application. Can someone give me some guidance as to what to look for?
Add note:
The java application I'm running is open source but I don't want to tweak it myself as I'm not capable of doing it. So what I'm looking at is on how to optimize the execution environment so as to fit the current behavior of the app. By the way, the application is hudson, a java-based continuous integration system.
Thanks in advance :)
Before start optimizing try to find out where you do you have a problem. Is your application CPU bound, memory-bound, or I/O bound? When you know this, try to find the biggest performance impact first and try to optimize it. Use Java profilers to find the problems in your application or configuration.
A good starting point for the whole process could be the Java Performance Tuning site.
Official Java Performance Documentation and Java SE Performance at a Glance
Read Java HotSpot VM options performance tuning.
Try unlock experimental VM options(-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC
-XX:+UseFastAccessorMethods).
Optimizes the code.
Before you attempt to optimise the JVM, I suggest you optimise your code. You can use a profiler like VisualVM (free) or YourKit (commercial) to look at CPU and memory performance bottleneck. Often simple changes can make a big difference.
Conversely, you can change lots of JVM options and not be sure its really helped.
Related
Is there any tool can measure execution time for each function call and find out bottle neck for a given developing java j2se project? Thanks!
Use profiling tools, such as YourKit, JProfiler and HPROF (this one is a command line tool).
You are looking for a profiler. I know that NetBeans includes a decent one.
You can also look at this question: Open Source Java Profilers.
It seems that the JDK 1.6 comes with a basic profiler. So maybe you want to give it a try first.It should be included with the VisualVM that comes with your jdk6: visualvm profiler
Yes, there are lot of tools - profiles like Netbeans Profiler or eclipse equivalent. Look at this course of JavaPassion to find out more about profiling tools and performance of Java applications.
Look at also this SO question to find out open source java profiles.
Consider the most precise and non-intrusive async-profiler.
IntelliJ IDEA Ultimate has built-in profilers support:
https://www.jetbrains.com/help/idea/cpu-profiler.html
You might try aspect oriented programming to intercept every method call and compute the duration.
Measuring is fine, but is a very indirect way to find bottlenecks. A very direct way is this: just hit ctrl-break several times, and examine the thread stacks.
Any bottleneck will be a line of code, nearly always a function call, and it will appear often on the stack of some thread. The worse it is, the more often it will appear.
Just look for any such often-appearing line of code. If you can figure out how to call it less, or not at all, you will save a bundle of time, guaranteed. Here's why.
Java JDK comes with JVisualVM under bin folder, once your application server (for example is running) you can run visualvm and connect it to your localhost, which will provide you memory allocation and enable you to perform heap dump
For more detailed steps on how to enable: http://sysdotoutdotprint.com/index.php/2017/08/01/turn-profiler-java/
I'm new into Java profiling, and I'd like to ask about it.
Does it make sense to profile an application on the server, where I only have the console?
Is there any console profiler which make sense?
Or should I profile the application only on localhost?
VisualVM is able to connect to a remote host. The profiling works the same way as local. It's part of the JDK since JDK 6 update 7.
When you do profiling you should generally try to reproduce the production environment as closely as possible. Differences in hardware (# of cores, memory, etc) and software (OS, JVM version) can make your profiling results as unique as the runtime environment.
For example, what looks like a CPU bottleneck worth optimizing on your local machine might disappear entirely or turn into a disk bottleneck on your production server depending on the differences in the CPU.
All modern profilers will allow to attach to a remotely running JVM so you don't need to worry about only having console access.
What profiler you decide to use will depend on your needs and preferences. Certain profilers will show you "hotspots" where your code is spending the majority of the time and these are often good candidates for optimization.
I prefer to use JProfiler for its extensive features and good performance. I previously used YourKit but switched to JProfiler for its memory and thread profiling features.
Does it make sense to profile an
application on the server, where I
only have the console?
Fortunately, that does not matter, since Java has always (well, for a long time, anyway) supported remote profiling, i.e. the Profiler can run on a different machine than the JVM being profiled and get its data via the network.
All Java profilers that I've ever seen support this, including visualvm, which comes with recent JDKs (in the bin directory).
There's a "quick and dirty" but effective way to find performance problems in Java.
This is a language-agnostic explanation of why it works.
Note that the JDK comes with a built-in profiler, HPROF. HPROF is a bit simplistic, but will find many problems. It is activated simply by invoking the JVM with parameter -agentlib:hprof; it will then automatically run as long as your JVM is running. It collects data until the JVM terminates, then dumps it into a file on the server, which you can analyze.
See e.g. http://java.sun.com/developer/technicalArticles/Programming/HPROF.html for a good introduction. A nice graphical analyzer for HPROF's results is PerfAnal: http://java.sun.com/developer/technicalArticles/Programming/perfanal/
If we have 300 classes in an application, is it possible to monitor how many instances of each class we have at a given time? Is it possible to know how much memory each instance is consuming?
Thanks
JDK 1.6 includes a tool called jvisualvm, which allows you to view lots of information about your running Java program, including memory usage, threads, etc. You could also use a profiler to see this kind of information. The profiler in NetBeans looks a lot like JVisualVM.
I personally like Yourkit. It has a very good UI and comes with a 30 day trial. The details are also pretty extensive.
The online help document in that site should help you on how to set things up for running it.
use profiler4j or pmd
personally i like profiler4J for its ease of use and simple graphics :)
use jvisualvm.exe it is part of the JDK6
Most profilers will give you this information. I'm personally familiar with JProfiler, but I expect any worthwhile profiler would let you do this.
For a more low-tech solution, you could even trigger a heap dump from your application and then look through it with an application like jhat. The interface leaves a lot to be desired, though, and profilers would be much more comfortable to use in any non-trivial case.
Edit: here is an example of the memory screen for JProfiler, and you can also investigate the reference chain.
You could use a Java profiler, depending on which web container (if it's a web-app) you're deploying to you can try alot of different profilers: http://java-source.net/open-source/profilers
I am calling a vendor's Java API, and on some servers it appears that the JVM goes into a low priority polling loop after logging into the API (CPU at 100% usage). The same app on other servers does not exhibit this behavior. This happens on WebSphere and Tomcat. The environment is tricky to set up so it is difficult to try to do something like profiling within Eclipse.
Is there a way to profile (or some other method of inspecting) an existing Java app running in Tomcat to find out what methods are being executed while it's in this spinwait kind of state? The app is only executing one method when it gets in this state (vendor's method). Vendor can't replicate the behavior (of course).
Update:
Using JConsole I was able to determine who was running and what they were doing. It took me a few hours to then figure out why it was doing it. The problem ended up being that the vendor's API jar that was being used did not match exactly to the the database configuration that it was using. It was defaulting to having tracing and performance monitoring enabled on the servers that had the slight mis-match in configuration. I used a different jar and all is well.
So thanks, Joshua, for your answer. JConsole was extremely easy to setup and use to monitor an existing application.
#Cringe - I did some experimenting with some of the options you suggested. I had some problems with getting JProfiler set up, it looks good (but pricey). Going forward I went ahead and added the Eclipse Profiler plugin and I'll be looking over the different open source profilers to compare functionality.
If you are using Java 5 or later, you can connect to your application using jconsole to view all running threads. jstack also will do a stack dump. I think this should still work even inside a container like Tomcat.
Both of these tools are included with JDK5 and later (I assume the process needs to be at least Java 5, though I could be wrong)
Update:
It's also worth noting that starting with JDK 1.6 update 7 there is now a bundled profiler called VisualVM which can be launched with 'jvisualvm'. It looks like it is a java.net project, so additional info may be available at that page. I haven't used this yet but it looks useful for more serious analysis.
Hope that helps
Facing the same problem I used YourKit profiler. It's loader doesn't activate unless you actually connect to it (though it does open a port to listen for connections). The profiler itself has a nice "get amount of time spent in each method" while working in it's less obtrusive mode.
Another way is to detect CPU load (via JNI, so you'd need an external library for this) in a "watchdog" thread with highest priority and start logging all threads when the CPU is high enough for a long enough time. You might find this article enlightining.
If it's for professional purpose and you have some money to spend, try to get your hands on JProfiler. If you just want to get some insights, try out the Eclipse Profiler Plugin. I used it several times, but I don't know the current state.
A new(?) project from the eclipse project itself is available too: http://www.eclipse.org/tptp/ (See this article). Never used it, so I can't tell if it is worth the effort.
There's also a very good list of open source profilers available at http://www.manageability.org/blog/stuff/open-source-profilers-for-java
If JConsole can't be used you can
press CTRL+BREAK under Windows
send kill -3 <process id> under Linux
to get a full Thread Dump. This doesn't affect performance and can always be run in production.
JRockit Mission Control Latency Analyzer.
The Latency Analyzer that comes with JRockit shows you what the JVM is "doing" when it's not doing anything. In the latest version you can see latencies for:
Java wait/blocked/sleep/parked.
File I/O
Network I/O
Memory allocation
GC pauses
JVM latencies, e.g code generation and class loading
Thread suspension
The tool will give you the stack trace when the latency occurred. You can view the latency data in many different ways (aggregated traces, as a histogram, in a thread graph etc.). The tool also allows you to see transitions between threads, for instance when one thread notifies another.
latency analyzer http://blogs.oracle.com/hirt/WindowsLiveWriter/The.0LatencyAnalyserMigratedfromtheoldBE_7246/latency_graph_2.png
The overhead is negligible and unlike many other tools it can be used in a production environment.
This blog post gives you a brief introduction and the program can be downloaded here.
It's free to use for development!
Use a profiler. Yes they cost money, and using them can occasionally be a bit awkward, but they do provide you with a great deal more real evidence rather than guesswork.
Human beings are universally bad at guessing where performance bottlenecks are. It just seems to be something our brains aren't build to do very well. It may seem obvious, you may have great ideas about what the problem is, but the real world often turns out to be doing something different. And optimising the wrong part of code means, at best, lots of work for minimal benefit. More often it makes things slower, and sometimes it breaks things entirely. So before you make any changes for the sake of optimisation, you should always have real evidence from a profiler or other accurate tool.
As mentioned, both JProfiler and YourKit are both fairly good and not prohibitively expensive. Last time I looked, they both had free demos too.
For completeness sake: even though my company more or less standardizes on Eclipse we use Netbeans (6 and up) with its included, free profiler on a daily basis. It works better than the Eclipse TPTP plugin (last checked 3 months ago) and for us it removes any need for a commercial profiler such as JProfiler, which is excellent, but fast becoming unnecessary.
VisualVM should be the profiler from netbeans as standalone. I tried the TPTP for eclipse but visualVm seems as a much nicer option!
I am reviewing a big java application to see if there are any performance bottlenecks. The real problem is that I cannot pinpoint the performance issues to any single module. The whole application is slow as such.
Is there some tool/technique I can use to help me out in this?
Try using a profiler on your running code. It should help you identify the bottlenecks. Try jprofiler or Netbeans profiler
I'm often happy enough using Java -Xprof. This gives you a sorted list of the functions your code spends most of its time in.
If you are running on Java 6 you can use the supplied monitoring tools
For testing/development purposes, you can download Oracle JRockit Mission Control for free from this site. (Requires Login, but accounts can be set up with any email adress)
Docs Here. It will allow you to find hotspots, memory leaks and much more.
As we see from How can I profile C++ code running in Linux?, the most statistically significant approach is to use a stack profiler.
Well, Java runs in the JVM, so getting a stack useful for C code won't be useful for us (it'll get the JVM stuff, not your code). Fortunately, Java has jstack! http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstack.html
It'll give you a bunch of threads, like the GarbageCollector. Don't worry about those, just look at where your threads are.
YourKit is a excelent java profiler (not free).