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 September 2004
Get rid of your performance problems and memory leaks!
Get rid of your performance problems and memory leaks!
Back to newsletter 046 contents
Threadaches (Page last updated August 2004, Added 2004-09-29, Author Chet Haase, Publisher java.net). Tips:
- Object creation/garbage collection can be fast but is not free. There is some overhead and this can add up if you do it too often (especially in a loop).
- If doing something repeatedly in a loop which only needs to be done once, move it out of the loop and do it once only.
- Thread context switching overhead can add up to reduce the benefits of using more threads.
- Your thread usage should try to match the resources available to the system. One CPU-intensive thread per CPU is probably optimal (non-CPU intensive threads don't count in this scenario).
- On today's computing platforms graphics hardware is inherently single-threaded so multiple drawing threads will not help (though note that some specialized tasks/systems do support parallelized graphic output).
- Multiple drawing threads can fill a graphics pipeline with extra drawing commands and actually slow down the drawing.
- Multithreading can be a big win in non-graphic tasks like parallelizing
I/O and avoiding blocking the GUI thread.
- Always test your application to see if you actually got the speedup you were anticipating.
WebSphere command caching (Page last updated August 2004, Added 2004-09-29, Author Joey Bernal Varaprasad Bhatta, Publisher IBM). Tips:
- How to cache depends on the type of data that you are caching and how that data is used.
- Generic HTML snippets can be cached as HTML fragments that are output from a servlet or JSP.
- Complex data types may need to be cached as an object or bean containing some discrete set of data.
- Caching does not always make up for bad design and coding practices; when you design and develop an application, you must consider performance and good coding practices for all aspects of the project lifecycle.
Building Highly Scalable Servers with Java NIO (Page last updated September 2004, Added 2004-09-29, Author Nuno Santos, Publisher OnJava). Tips:
- Most thread libraries do not scale well, because the time required for context switching increases significantly with the number of active threads.
- With a few hundred active threads, most CPU time is wasted in context switching, with very little time remaining for doing real work.
- Single threaded, I/O cannot hide the latency of disk I/O or take advantage of systems with multiple CPUs.
- A server application should have at least 2*n threads, with n being the number of execution units available.
- A selector, its selection keys, and registered channels should never be accessed by more than one thread.
- The simplest way of avoiding the concurrency problems between dispatcher and worker threads is to have the dispatcher threads do the work.
- If the number of simultaneous clients will never exceed more than one or two hundred, then go for a simple blocking threaded model.
- If you plan to support many hundreds or thousands of simultaneous clients, you should definitely consider using I/O multiplexing.
- The multiplexing router was able to handle 10,000 clients with no significant drop in throughput - an equivalent thread per client model only reached 3,000 clients with a significant accompanying drop in throughput.
Alerts in MIDP 2.0 (Page last updated August 2004, Added 2004-09-29, Author Eric Giguere, Publisher Sun). Tips:
- Report on progress if an operation will take time, - reassurance that
the application hasn't stopped reduces the user's uncertainty and impatience.
- MIDP 2.0 supports gauge component progress indicators (must be: non-interactive; not associated with any other container; label null; have no commands or command listeners; preferred sizes unlocked; have a default layout), e.g. new Gauge( null, false, max, initial ). Associate the gauge with an alert using the Alert.setIndicator().
- You can update a gauge's value at any time and from any thread, because the MIDP user interface classes are thread-safe.
High Volume Batch Transaction Processing (Page last updated April 2004, Added 2004-09-29, Author Lara D'Abreo, Publisher DevX.com). Tips:
- High-volume business processes, such as bulk data upload and downloads, data cleansing, report generation, etc., are best performed as batches.
- Batch processes are optimized to achieve the maximum throughput for a particular task, usually prioritizing performance over flexibility.
- The key to achieving parallelism in J2EE is the ability to partition your job into smaller units of work (chunks) that can be processed in parallel.
- By partitioning prior to execution, you preempt any potential locking problems that thread contention causes and you can assume efficient optimistic locking strategies.
- The simplest way to achieve parallelism in J2EE is to initiate and control your threads from a client-side thread pool outside your application servers.
- For optimal design, the session bean should delegate work to a batch specific worker - transaction failures have to handled in chunks, not row-by-row.
- Your batch framework should provide a controlled mechanism for halting the batch processes in mid flow without corrupting data.
- Minimize obstructions to your batch pipeline by assembling all the data upfront and passing it downstream.
- Efficient batch processes will be CPU/memory bound not I/O bound.
- I/O-bound functions are harder to scale than CPU-bound ones.
- Run your batch processes during quiet times when resources are available and data is stable.
- Run the batch in a number of transactions for increased robustness. This is classic tuning, there is probably an optimal transaction size for performance, resources and robustness.
- Don't pass too much data across the wire between your chunkers and workers. Pass the bare minimum amount of data necessary to assist your worker input queries.
- The most efficient approach is to queue the work, and process in batches re-queueing any that need re-processing.
- Try not to obstruct your flow with redundant data lookups, looping constructs, unnecessary logic, or abstraction patterns.
- Batch-processing code should be as streamlined as possible and, in most cases, procedural in nature: no unnecessary object creation, string manipulation, I/O, logging, or validation checks.
- Avoid initiating new transactions using TX_NEW or explicit rollbacks.
Using the New Concurrent Utility Classes in Java 5.0 (Page last updated September 2004, Added 2004-09-29, Author Tim Stevens, Publisher informIT). Tips:
- java.util.concurrent.CountDownLatch allows you to queue up a number of threads and start them all at once.
- java.util.concurrent.ScheduledExecutorService controls a pool of threads can be set to run repeatedly at regular intervals after an optional initial delay.
- java.util.concurrent.ConcurrentLinkedQueue allows concurrent reading and writing of the queue.
- You should typically put unlock calls in a finally block to ensure that regardless of exceptions objects are not left in a locked state.
- java.util.concurrent.ReentrantReadWriteLock allows for multiple concurrent read locks.
- java.util.concurrent.Executor is an interface that defines a single method, execute(Runnable), but the various implementations enable us to monitor pools of threads and maintain control over their status.
Some Other New Features in Java 2 Standard Edition 1.5 (Page last updated August 2004, Added 2004-09-29, Author Dean Wette, Publisher OCI). Tips:
- java.lang.StringBuilder represents an unsynchronized mutable sequence of characters useful as a replacement for StringBuffer in single-threaded applications
- An enumerated type Thread.State represents the various possible states a thread may have, and is returned by the new Thread.getState() method for purposes of monitoring thread state
- System.nanoTime() is a new method for measuring elapsed time with the more precise granularity than available previously, where supported by the underlying operating system
State replication in the Web tier (Page last updated July 2004, Added 2004-09-29, Author Brian Goetz, Publisher IBM). Tips:
- J2EE provides several means of managing session state: the data tier; HttpSession objects; stateful session beans; cookies; or hidden form fields (the latter two are security risks).
- Injudicious management of session state can cause serious performance problems.
- If the business objects are stateless, then the application can often be scaled by simply adding more Web servers, rather than more Web servers and more EJB containers, which is generally less expensive and easier to do.
- Storing conversational state in the database can be prohibitively expensive.
- Session replication enables a host of benefits -- load balancing, scalability, fault tolerance, and high availability.
- Replicating session state coherently across a cluster has a considerable performance cost and may also have scalability problems as the cluster approaches a certain size.
- A common approach is to combine load balancing with session affinity -- the load balancer is able to associate connections with sessions and route subsequent requests within a session to the same server.
- One approach for session replication is simply to serialize the session contents and write it to a database. There is a performance cost -- database transactions are expensive, and while it scales well in the Web tier, it may create a scaling problem in the data tier -- if the cluster grows large enough, it may be difficult or cost-prohibitive to scale the data tier to accommodate the volume of session data.
- File-based replication is less reliable than database-based replication.
- Memory-based replication costs memory resources and network bandwidth. Also, in the event of failover, the session state might be "stale".
- Keep the session size minimal.
- Don't bypass setAttribute, otherwise optimizations the container automatically supports could be bypassed.
- Use fine-grained session attributes rather than large monolithic objects.
- When the session is finished call HttpSession.invalidate().
- Eliminate objects from the session data as soon as they are no longer needed.
Back to newsletter 046 contents
Last Updated: 2021-03-29
Copyright © 2000-2021 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.
RSS Feed: http://www.JavaPerformanceTuning.com/newsletters.rss
Trouble with this page? Please contact us