Java Performance Tuning
Java(TM) - see bottom of page
Our valued sponsors who help make this site possible
JProfiler: Get rid of your performance problems and memory leaks!
Training online: Concurrency, Threading, GC, Advanced Java and more ...
Tips June 2017
JProfiler
|
Get rid of your performance problems and memory leaks!
|
JProfiler
|
Get rid of your performance problems and memory leaks!
|
|
|
Back to newsletter 199 contents
https://www.youtube.com/playlist?list=PL9rzqHHCiIVQr27ZsP0_r8eOgQMTbhJfF
Java Performance Pitfalls: improper caching, database access, improper logging, XML and JSON (Page last updated January 2017, Added 2017-06-27, Author Jeroen Borgers, Peter Paul Bakker, Publisher rabobank). Tips:
- Identify all remote calls (including database calls): number of calls per request and amount of data transferred.
- Determine the memory usage: http sessions, caches, pools, number of entries, amount of data.
- Pitfalls found include: Too much session usage; too much backend interaction; improper caching; reloading lists of values; inefficient database access; improper use of XML and remoting; using XPath; improper logging; inefficient streaming IO; unnecessary ise of reflection; non-safe threads and lock contention; unnecessary execution; inefficient memory usage; improper use of collections, inefficient String usage; inefficient data-time formatting; using slow library calls.
- Caching disdvantages include: taking more memory; locking around cache access; low hit-ratios make the whole cache inefficient.
- Keep your locks to as small a scope as possible.
- Cache keys need to be short, cheap to generate, consistent and well chosen for access.
- Cache TTLs should be defined appropriately for the data.
- Use caches to protect against repeated refreshing causing effective denial-of-service.
- Monitor the hit-ratio of the caches to ensure the caching is effective.
- Inefficient database communications include: missing indexes; fetching rows individually instead of batching; doing in Java what it would be efficient to do in the database; badly doing object-relational mapping.
- Tune JDBC fetch-size to improve database communication efficiency.
- Minimize logging to essential information so that performance is not impacted. There is too much logging if you are exhausting disk space or causing user-waits from the overall IO.
- Only log stacktraces when it is a code error, not input errors etc.
- Use conditionally guarded logging or lambdas or avoid concatenation (or use placeholders that get filled in with .toString() calls by the logging framework).
- Be aware that Mapped Diagnostic Contexts uses thread-local memory, so remove elements when no longer needed (minimize scope).
- Try to use asynchronous logging (and flush on shutdown), but note this now uses more memory as there will be an in-memory queue. Monitor the queue size.
- XML-Object binding is expensive and slow. JSON is better, though binary protocols are best.
- If using XML, reduce the messsage size to only those elements needed. Disable validaton (in production) if possible.
- JAXBContext objects are heavy, and thread-safe so reuse them. But the support classes like marshalling are not thread-safe.
- Jackson ObjectMapper is expensive but thread-safe and so should be resused.
- Several properties let you specify XML factories which improves efficiency: Djavax.xml.* (parsers, transform, etc).
- Use custom date conversion with JAXB (rather than the JAXB one) for efficiency.
https://www.youtube.com/watch?v=Q895_B9BhJ8
Using Java 8 Lambdas and StampedLock To Manage Thread Safety (Page last updated May 2017, Added 2017-06-27, Author Heinz Kabutz, Publisher Devoxx). Tips:
- StampedLock let's you do optimistic reads (ReentrantReadWriteLock only does pessimistic reads).
- StampedLock is usually much faster than ReentrantReadWriteLock.
- StampedLock lets you upgrade a read to a write lock (ReentrantReadWriteLock doesn't do that).
- StampedLock is not reentrant, you can deadlock if you attempt to get a write lock on the same object in the same thread.
- StampedLock optimistic read pattern is
stamp = lock.tryOptimisticRead();readState();if (!lock.validate(stamp)){stamp = lock.readLock();readAndUnlockState();}
- ArrayOutOfBoundsException, ClassCastException and NullPointerException can be very cheap exceptions because the JVM optimizes by not filling in the stack trace if they happen often in a particular place.
- 5 ways to do atomic optimistic reads on multiple fields are: StampedLock, AtomicReference, AtomicReferenceFieldUpdater, Unsafe, VarHandle.
- The fastest way to get an int from a string is
""+i
, not Integer.toString(i)
because of JVM optimizations.
- Use synchronized rather than Lock objects as its much easier and well optimized, unless you find that there is an actual measured contention issue that needs higher concurrent performance. Even then, try using ThreadLocals is that can work instead of locking.
http://www.devx.com/Java/best-practices-for-multithreading-in-java.html
Best Practices for Multithreading in Java (Page last updated March 2017, Added 2017-06-27, Author Joydip Kanjilal, Publisher DevX). Tips:
- The creation of threads and their execution in a multithreaded environment is an expensive process, primarily due to the overhead involved in context switches between threads.
- For multithreaded applications to be high performing, secure and scalable use these practices: Use immutable types, they are thread-safe; minmize the scope within locks; use local variables where you can to minimize scope; avoid static objects where possible though static final is fine if the object itself is immutable or thread-safe; use concurrent collections that have minimal locking.
- [The advice to use locks instead of synchronized is no longer valid with Java 8+; for many scenarios synchronized is now better, and it's much more readable and understandable. Current best practice is to use synchronized, and only switch to locks if there is a specifically identified performance issue.]
https://www.infoq.com/articles/Troubleshooting-Java-Memory-Issues
Troubleshooting Memory Issues in Java Applications (Page last updated March 2017, Added 2017-06-27, Author Poonam Parhar, Publisher InfoQ). Tips:
- "OutOfMemoryError: Java Heap Space" means that the JVM does not have any free space left in the Java heap - commonly because the specified maximum Java heap size is not sufficient to accommodate the full set of live objects. The Java heap size can be increased using the -Xmx JVM option.
- A memory leak occurs when an application unintentionally holds references to objects in the heap, preventing them from being garbage collected.
- It is always a good idea to enable GC logging, even in production environments, eg -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:[gc_log_file]
- If the live-set is increasing over time even after the application has reached a stable state then that could indicate a memory leak.
- Heap usage can be monitored with many tools including JVisualVM, Java Mission Control, JConsole, as well as the GC logs.
- Heap dumps have the most useful data for troubleshooting memory leaks. Heap dumps can be collected using jcmd, jmap, JConsole and the HeapDumpOnOutOfMemoryError JVM option:
jcmd process_id/main_class GC.heap_dump filename=heapdump.dmp
, jmap -dump:format=b,file=snapshot.jmap pid
, JConsole utility, using Mbean HotSpotDiagnostic and -XX:+HeapDumpOnOutOfMemoryError
- The parallel garbage collector can continuously attempt to free up room on the heap by invoking frequent back-to-back Full GCs - this can be avoided by tuning the values for -XX:GCTimeLimit (default 98%) and -XX:GCHeapFreeLimit (default 2%).
- Heap histograms can give a quick view of the objects present in your heap, and comparing these histograms can help find the top growers in our Java heap. Obtainable with
-XX:+PrintClassHistogram
and Control+Break, jcmd [process id/main class] GC.class_histogram filename=Myheaphistogram
, jmap -histo pid
, jmap -histo [java] core_file
- Java Flight Recordings with heap statistics enabled can be really helpful in troubleshooting a memory leak by showing the heap objects and the top growers in the heap over time. To enable heap statistics, you can use Java Mission Control and enable the 'Heap Statistics' by going to 'Window->Flight Recording Template Manager'.
- An OutOfMemoryError can be caused due to excessive use of finalizers if the finalizer thread does not keep up with the rate at which the objects become eligible for finalization. Use
jmap - finalizerinfo
to check the finalizer queue size. jmap -permstat
and jmap -clstats
are useful here too.
Jack Shirazi
Back to newsletter 199 contents
Last Updated: 2025-03-25
Copyright © 2000-2025 Fasterj.com. All Rights Reserved.
All trademarks and registered trademarks appearing on JavaPerformanceTuning.com are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. JavaPerformanceTuning.com is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
URL: http://www.JavaPerformanceTuning.com/news/newtips199.shtml
RSS Feed: http://www.JavaPerformanceTuning.com/newsletters.rss
Trouble with this page? Please contact us