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 January 2006
JProfiler
|
Get rid of your performance problems and memory leaks!
|
JProfiler
|
Get rid of your performance problems and memory leaks!
|
|
|
Back to newsletter 062 contents
http://devnet.developerpipeline.com/documents/s=9851/q=1/ddj0602f/0602f.html
Dynamic Bytecode Instrumentation (Page last updated February 2006, Added 2006-01-30, Author Ian Formanek and Gregg Sporar, Publisher DrDobbs). Tips:
- Large applications tend to be those that most need profiling.
- Dynamic bytecode instrumentation lets you control precisely which parts of an application are profiled; only relevant information is reported, and the impact on application performance is minimized.
- Instrumentation added by a profiler can cause the application to run differently?which may change the performance problem symptoms, making it harder to find the cause of the problem.
- Larger applications tend to have larger heaps and more threads. Profilers will deliver information on all of these things, which is usually more information than you can interpret efficiently.
- Java profiling tools use the Java Virtual Machine Profiling Interface (JVMPI), or the Java Virtual Machine Tool Interface (JVMTI), and byte injection for doing instrumentation of an application.
- For CPU performance profiling, bytecodes are typically inserted at the methodEntry() and methodExit() calls.
- For memory profiling, bytecodes are typically inserted after each new or after each constructor.
- Bytecode insertion is usually done either by a post-compiler or a custom class loader.
- Static bytecode instrumentation imposes a set overhead on the application which is usually unnacceptablly high if you want sufficient information to actually be able to diagnose problems.
- Using JVMPI/JVMTI features disables many VM optimizations.
- Garbage collection cannot be monitored using bytecode instrumentation.
- Sampling (typically every 10 to 100 milliseconds) is an alternative to instrumentation, but cannot profile memory, is less accurate and has an overhead that grows according to the number of threads.
- Dynamic bytecode instrumentation inserts and removes bytecodes using the JVMTI's redefineClass(Class[] classes, byte[][] newBC) method. Profiling can be turned off with no residual overhead, and there is no need to restart the application to add in instrumentation.
- The profiler must instrument not only the selected root methods, but also all methods that it invokes, iteratively for the whole call chain. To minimize overheads, instrumentation code must exit immediatly if a root method is not in the call chain.
- Efficient memory profiling tracks only a subset of the allocated objects. Tracking as few as 10 percent of the allocated objects usually yields the same information, but with much less overhead.
- The normal approach to identifying memory leaks is to compare heap snapshots over time. This can be of limited use in large applications or where the leaking objects are not obvious or if the leak is very slow.
- A statistical approach for identifying memory leaks can work well with low overhead, using two key metrics: the age of each object (number of garbage collections it has survived) and the generation count for each class (the number of different ages of all objects of that class). A high class generation count indicates that your application is continuing to allocate new objects of that class without letting go of references to older objects of that class, possibly indicating a memory leak.
- By choosing a single root method to instrument from, it is possible to focus on a specific area of runtime perormance with minimal overhead but an acceptable level of detail.
- Example of tracking a memory leak with reduced overhead: only track every 10th allocation; list live classes by generation count; select the most interesting memor leak candidates and get allocation stack traces; target the traces with the largest generation counts.
http://blogs.sun.com/roller/page/swinger?entry=swingworker_throttling_and_monitoring
SwingWorker Throttling and monitoring (Page last updated January 2006, Added 2006-01-30, Author Antonio Vieiro, Publisher Sun). Tips:
- If you have a big number of tasks to execute asynchronously don't use a thread for each one.
- To keep resource-consumption under control, throttle. Use a pool of M of simultaneous threads to execute N tasks (typically M < N).
- Building a pool of threads using Java 5 is easy:
ExecutorService threadPool = Executors.newFixedThreadPool( POOL_SIZE );
And submitting work to the pool is equally easy: Callable mySwingWorker = ...; threadPool.submit( mySwingWorker );
- A pool of threads could be monitored to determine the list of currently executing tasks; the tasklist average wait times and run times; and allow time-outs.
- The SwingWorker implementation in JDK 6 has a (fixed-size?) pool of 10 threads.
http://www.informit.com/guides/content.asp?g=java&seqNum=16
Multithreaded Java Programming (Page last updated May 2005, Added 2006-01-30, Author Steven Haines, Publisher informit). Tips:
- There are two mechanisms for waiting threads to become aware of a condition: polling or notification.
- A typical polling loop is easy to code:
while( running ) { if( checkForItem() ) { consumeItem(); } Thread.sleep( 1000 );}
. However polling is not efficient, especially with many threads polling, and also leads to a delay in identifying the condition change - minimizing that delay requires larger cpu consumption from more frequent polling.
- The notification model is more efficient than polling: the thread waits and is notified when the state it waits on changes. No polling means no unneeded impact on the CPU and also the condition change is operable on as soon as possible.
- A typical wait loop looks like:
while( queue.isEmpty() ) { try { wait(); } catch( InterruptedException ie ) { ie.printStackTrace(); } } queue.removeFirst();
(another thread would be excuting queue.add( message ); notifyAll();
)
http://www.articlecity.com/articles/computers_and_internet/article_2233.shtml
Scalability Testing - 7 Tips For Improvement (Page last updated January 2006, Added 2006-01-30, Author Mark Trellis, Publisher articlecity). Tips:
- Systems tested or deployed on a small scale can fail to meet performance goals when the deployment is scaled up to support real levels of use.
- Risk assessment should recognise that scaling is amongst the biggest risks.
- Incorporating externally provided services into your overall solution means that your ability to scale now depends upon these external system operate under load.
- You should develop large scale software systems with performance clearly in mind, particularly scalability testing, volume testing and load testing.
- Research and quantify the data volumes and transaction volumes the target market implies - this should be a requiement for any feature development.
- Single-user functionality does not necessarily scale - you need to provide equivalent functionality that does scale.
- Load test at representative scales on each incremental software release.
- Load testing is not just about measuring response times with a performance test. Load testing needs to include stress testing, reliability testing, and endurance testing.
- Failure testing, fail-over testing and recovery testing carried out on representative scale systems operating under load should be included to test component fail-over.
- Test external service provision at scales you need.
- The system architecture should include graceful response and fall-back operation should external services deteriorate or fail.
http://weblogs.java.net/blog/alexfromsun/archive/2006/01/debugging_swing_2.html
Debugging Swing (Page last updated January 2006, Added 2006-01-30, Author Alexander Potochkin, Publisher java.net). Tips:
- Make Swing methods threadsafe by moving calls on the Event dispatching thread: if (!SwingUtilities.isEventDispatchThread()) {SwingUtilities.invokeLater(new Runnable() {public void run() { /*code to execute*/ } } ) } - but note that this technique produces an additional inner class for each call, making Swing bigger and slower.
- Make Swing methods threadsafe by moving calls on the Event dispatching thread: if (!SwingUtilities.isEventDispatchThread()) {Callable callable = new Callable() {public T call() throws Exception { /*code to execute*/ }}; RunnableFuture future = new FutureTask(callable); SwingUtilities.invokeLater(future); try {return future.get();} catch (...){...} } else {return /*code to execute*/}
Jack Shirazi
Back to newsletter 062 contents
Last Updated: 2025-01-27
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/newtips062.shtml
RSS Feed: http://www.JavaPerformanceTuning.com/newsletters.rss
Trouble with this page? Please contact us