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 December 2013
JProfiler
|
Get rid of your performance problems and memory leaks!
|
JProfiler
|
Get rid of your performance problems and memory leaks!
|
|
|
Back to newsletter 157 contents
http://blogs.mulesoft.org/chasing-the-bottleneck-true-story-about-fighting-thread-contention-in-your-code/
Chasing the bottleneck: True story about fighting thread contention in your code (Page last updated October 2013, Added 2013-12-29, Author Mariano Gonzalez, Publisher mulesoft). Tips:
- Monitor thread contention by keeping track of threads waiting to acquire a lock.
- Deadlocks are easily diagnosed by getting a stack trace, the precise method (and code line if the debug info is present) where the deadlock has occurred will be listed.
- Having more potentially active threads than cores while still measuring a low overall CPU utilisation indicates that contention of some sort is preventing the threads from being able to process concurrently.
- Thread pools have various strategies to deal with incoming work when all threads are busy, e.g.: rejecting the excess work; waiting; executing the job in the thread adding the work. In the last case, this could potentially cause the work pipeline to stall behind one work item, even if the pool becomes free to accept more work, so should be considered carefully. The symptom for this situation would be for the "adding" thread to be busy while many of the pool threads become idle.
- A lot of system CPU being used could indicate contention - too large a size for a thread pool of CPU bound work would actually slow down processing as the system attempts to context switch the threads to give each a fair slice of CPU (in the example given, a thread pool of size 100 on a 16 core box, processing CPU-bound work, actually processed the overall work at a slower rate than when the pool size was reduced to 16).
- Try to keep synchronized blocks to a minimum.
http://www.javaspecialists.eu/archive/Issue215.html
StampedLock Idioms (Page last updated December 2013, Added 2013-12-29, Author Dr. Heinz M. Kabutz, Publisher The Java Specialists' Newsletter). Tips:
- [Article shows a number of different techniques for locking and a non-locking solution to the same problem: synchronized/synchronized+volatile/ReentrantLock/ReentrantReadWriteLock/StampedLock/Atomic]
- A combination of volatile and synchronized allows you to maintain correct concurrent update semantics to a variable, while providing a fast non-locking read access.
- synchronized was greatly improved from Java 6, so that performance is similar to ReentrantLock in contended cases. In uncontended cases, synchronized locks can sometimes be automatically optimized away at runtime, leading faster performance.
- The only reason to use ReentrantLock instead of synchronised after Java 6 is if you'd like to use the more advanced features such as better timed waits, tryLock, etc (i.e. being able to break a deadlock).
- ReentrantReadWriteLock differentiates between exclusive and non-exclusive locks. If a thread is currently holding the write lock, then any reader thread will get suspended until the write lock is released again.
- The overhead of using a ReentrantReadWriteLock is substantial - ballpark figure, you need the code in the read lock to execute for about 2000 clock cycles in order to win back the cost of using it, otherwise you would probably be better off just using a normal ReentrantLock.
- StampedLock (which is non-reentrant) has tryOptimisticRead() and validate() which in combination provides a potentially higher throughput read.
http://codingjunkie.net/striped-concurrency/
Fine-Grained Concurrency with the Guava Striped Class (Page last updated September 2013, Added 2013-12-29, Author Bill Bejeck, Publisher codingjunkie). Tips:
- Synchronize the smallest portion of code possible.
- Restricting access for N number of threads is a natural fit for a java.util.concurrent.Semaphore object.
- Guava Striped class can create locks lazily, e.g. with Striped.lazyWeakSemaphore(numberStripes,permits).
- The Guava Striped class allows you to maintain size restricted maps of concurrency control objects (Lock, Semaphore, and ReadWriteLock) to apply to resources (one map per resource) - the "striping" is an abstract of the striping used in ConcurrentHashMap.
https://weblogs.java.net/blog/kcpeppe/archive/2013/11/10/fun-lambdas
Fun with Lambda's (Page last updated November 2013, Added 2013-12-29, Author Kirk Pepperdine, Publisher java.net). Tips:
- The loop while((l = BufferedReader.readLine()) != null) {...}is replaced with BufferedReader.lines() using Java8 Lambdas.
- Once you have a Stream in Java 8, you can use the Stream.parallel() method to make it a stream that processes in parallel, without altering any of the other Stream operations.
- An example of extracting numerical data by regex in parallel from a file using lambdas would be:
Pattern somePattern = Pattern.compile("xxx\\((\\d+)");String s = Files.lines(new File("somepath").toPath()).parallel().map(somePattern::matcher).filter(Matcher::find). mapToDouble(matcher -> Double.parseDouble(matcher.group(1))). summaryStatistics().toString());
http://java.dzone.com/articles/javalangoutofmemory-permgen
Java.lang.OutOfMemory: PermGen Space - Garbage Collecting a Classloader (Page last updated October 2013, Added 2013-12-29, Author Raji Sankar, Publisher DZone). Tips:
- Recreating a leak under controlled conditions - preferably without having to wait a long time for the leak to show - is half way towards fixing it
- Use
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=somePath
to generate a heap dump when your process first goes out-of-memory
- jmap let's you generate heap dumps from the JVM at any time, e.g. with jmap -dump:format=b,file=heap.bin "pid"
- jmap -permstat "pid" shows the classloaders in the perm gen space and their status if they are live or dead.
- visualvm let's you view a heap dump, and can show the nearest GC root that is holding an object preventing it from being garbage collected.
- static variables holding on to objects will keep all the objects referenced from those objects (and the objects they reference, and so on) alive. You need to dereference objects from static variables (e.g. cached objects) when you are done with them to let them be garbage collected.
- Custom classloaders can have subtle memory retention issues, such as default protection domains that keep alive classloaders - and hence all the classes they load.
- Shutdown all ThreadPools when you're finished with them so that the threads are released.
- Remove all ThreadLocals once used, and release them.
- If threads are loaded by the Bootstrap classloader and you have called a setContextClassloader, remove it.
http://timontech.net/2013/09/25/183/
Optimize Late and Not Often (Page last updated September 2013, Added 2013-12-29, Author Tim Kitchens, Publisher Tim on Technology). Tips:
- When you go off on "optimization tangents" (over-engineering), you lose valuable development cycles, cycles that could have been used to deliver something that actually provides a tangible benefit. Ask yourself whether the optimization is being done for an actual (measured) need, rather than just an imagined need.
- Optimization very often results in code that is more difficult to understand and maintain, so shouldn't be done unless it's actually required.
- Make correct system functionality and then clean design your top priorities, not fast code or minimum resource usage.
- Create performance and scalability tests that can identify bottlenecks and automate these tests.
- Make performance tests as realistic as possible, with a mix of use cases, running parallel threads that mimic anticipated runtime behavior.
- If the non-functional requirements don't indicate a need for a higher level of performance, spend your time elsewhere.
- Prove where the system is not meeting defined performance needs and then systematically move through the process of identifying and remedying these issues.
Jack Shirazi
Back to newsletter 157 contents
Last Updated: 2024-08-26
Copyright © 2000-2024 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/newtips157.shtml
RSS Feed: http://www.JavaPerformanceTuning.com/newsletters.rss
Trouble with this page? Please contact us