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!
Newsletter no. 4, March 21st, 2001
Get rid of your performance problems and memory leaks!
Get rid of your performance problems and memory leaks!
This month I've pulled out those Weblogic tips I promised. In
addition we've listed Java performance articles on the full
range of development: managing performance; designing
performance; server-side performance; client-side performance;
games performance; JDK 1.4 performance improvements; and more.
The two JDBC performance tuning articles listed (one Weblogic's,
one IBM's) are probably the best ones I've seen on that subject.
We've also had a bunch of tool references sent in to us. And last,
but not least, Kirk continues his diverse and edifying roundup.
Finally, a note for our Japanese readers. Yukio Andoh has kindly
volunteered to translate the newsletters into Japanese: there will
probably be a delay of a week or so, after which you can find the
Japanese version at
Sun have scheduled an interesting sounding community chat
session with Steve Wilson and David Stoutamire, entitled
'Tuning the Java Runtime Environment for "Big Iron"'
scheduled for March 27 11:00 a.m. Pacific Time/7:00 p.m. GMT.
All the following page references have their tips extracted below.
Older Pages (including Weblogic tips)
All the following page references have their tips extracted below.
Other additions to the website
Here is this month?s roundup of the performance tuning discussions
down at the Saloon in the Java Ranch (www.javaranch.com).
One participant was looking to see if he could measure run times
down to the microsecond. We never learned why someone would want
this level of precision. But, it is interesting that just about
everyone repeatedly loops short calls to obtain timings on those
short calls. I would think that unless the loop itself represented
a loci of execution, then you?d be better off spending your time
Which technology among JSP, CORBA, SERVLETS, ASP should be used to
achieve the best response time? This very loaded question came up.
Each of these technologies has a cost but also brings benefits.
Some might consider that since JSP is compiled into Servlets then
just using a Servlet might bring more performance. That, of course,
would be assuming that the JSP compiler was not as good at creating
code as your developers may have been. Creating a benchmark that is
applicable to your situation is usually the best way to answer these
An interesting point regarding swapping, GC, and performance came out
of a discussion on what the largest max heap size setting could be.
To summarize, the respondent quite correctly pointed out that one
should not set max heap size to a value larger than physical memory.
If the system has a fair amount of churn, then there could be a large
number of objects waiting for GC. Thus GC could cause a lot of
swapping which could have a detrimental effect on performance.
Is it better to use an iterator or convert your collection to an
array? The assumption here is that direct access to an element in
an array is much faster than using the iterator. One respondent
commented that the difference is maybe between 2 to 13 times faster.
In light of this, another patron offered some heuristics for making
the choice. You need to consider the cost of conversion and the number
times that you?ll be iterating through the array. Again, this
represents another example of where a benchmark may help clear things
If you mosey on over to The Server Side?s (www.theserverside.com)
performance tuning folks, you?ll find there?s a lengthy discussion
going on about weak and soft references. An object that is held only
by a WeakReference will be GC?ed as soon as possible. An object that
is held only by a SoftReference will be GC?ed when a VM is short on
memory. That?s the theory. In practice, one participant noted that
"VMs eat references like there?s no tomorrow". Even so, if you?re
implementing a cache, then using a SoftReference may give you
advantages in the future.
Can using an OODB improve your performance? In my experience, it
can reduce the amount of code that you deliver by about 40% (JDBC
not included). An OODB seems to help when: your DOM is quite complex;
or where you have high scaling requirements.
Java vs. Stored Procedures: how do you decide between them? A theme
that was repeatedly echoed was where one needed to increase
performance by reducing the number of network round trips. This is
a very familiar solution to a very common problem in distributed
computing. There were some red flags raised concerning design.
Since my outlook is very OO, I?ll side with the contributors that
only pushed application logic into a stored procedure when performance
dictated it. If you wish to form your own (possibly more objective)
view, I recommend that you check out the discussion for yourself.
You?ll be glad that you did.
Performance planning for managers (Page last updated February 2001, Added 2001-03-21, Author Jack Shirazi). Tips:
- Include budget for performance management.
- Create internal performance experts.
- Set performance requirements in the specifications.
- Include a performance focus in the analysis.
- Require performance predictions from the design.
- Create a performance test environment.
- Test a simulation or skeleton system for validation.
- Integrate performance logging into the application layer boundaries.
- Performance test the system at multiple scales and tune using the resulting information
- Deploy the system with performance logging features.
Designing Entity Beans for Improved Performance (Page last updated March 2001, Added 2001-03-21, Author Beth Stearns). Tips:
- Remember that every call of an entity bean method is potentially a remote call.
- Designing with one access method per data attribute should only be used where remote access will not occur, i.e. entities are guaranteed to be in the same container.
- Use a value object which encapsulates all of an entity's data attributes, and which transfers all the data in one network transfer. This may result in large objects being transferred though.
- Group entity bean data attributes in subsets, and use multiple value objects to provide remote access to those subsets.
Pseudo Sessions for JSP, Servlets and HTTP (Page last updated March 2001, Added 2001-03-21, Author Budi Kurniawan). Tips:
- Use pseudo sessions rather than
HttpSessions to improve web server scalability.
- Pseudo sessions reside on file instead of in memory, thus both decreasing memory and allowing sessions to be distributed across multiple servers.
Clustering for J2EE and Java application servers. Looks at Bluestone Total-e-server, Sybase Enterprise Application Server, SilverStream Application Server, and WebLogic Application Server. (Page last updated February 2001, Added 2001-03-21, Author Abraham Kang). Tips:
- A cluster in this context is a group of machines working together to transparently provide enterprise services.
- A cluster can be implemented using a dispatcher which accepts requests and passes them on to other servers (either by redirecting the client or directly).
- Clusters target to provide scalability and high-availability.
- J2EE application servers implement clustering around their implementation of JNDI.
- Clustering should allow failover if a machine/process crashes. For stateful sessions, this requires state replication.
- Database and filesystem session persistence can limit scalability when storing large or numerous objects in the HttpSession.
- To scale the static portions of your Website, add Web servers; to scale the dynamic portions of your site, add application servers.
Tracking Memory leaks (Page last updated February 2001, Added 2001-03-21, Author Jim Patrick). Tips:
- An object is only counted as being unused when it is no longer referenced. If objects remain referenced unintentionally, this is a memory leak.
- If you get a java.lang.OutOfMemoryError after a while, memory leakage is a strong suspect.
- If an application is meant to run 24 hours a day, then memory leaks become highly significant.
- Most JVMs grow towards the upper heap limit (-Xmx/-mx options) when more memory is required, and do not return memory to the operating system, even if the memory is no longer needed, until the JVM process terminates.
- [Article provides an example of tracking memory leaks using JProbe].
Benchmarking JMS (Page last updated March 2001, Added 2001-03-21, Author Dave Chappell, Bill Wood). Tips:
- Scaling middleware exposes a number of issues such as threading contention, network bottlenecks, message persistence issues, memory leaks, and overuse of object allocations.
- [Article dicusses questions to ask when setting up benchmarks for messaging middleware].
- Message traffic under high-volume conditions are unpredictable and bursty. Messages can be produced far faster than they can be consumed, causing congestion. This condition requires the message sends to be throttled with flow control (could be an exception, or an automatic resend).
- When testing performance, run overnight and over weekends to generate longer term trends. Some concerns are: testing without a real network connection can give false measures; low user simulation can be markedly different from high user simulations; network throughput may be large than the deployed environment; nonpersistent message performance is dependent on processor and memory; disk speed is crucial for persistent messages.
- [Article provides a benchmark harness for testing JMS].
Designing Java Performance: reducing object creation (Page last updated March 2001, Added 2001-03-21, Author Brian Goetz). Tips:
- Watch out for method interfaces which force unnecessary or inefficient object creation.
- Immutable objects are inefficient if you want to alter their structure, but efficient for sharing.
- One way to avoid creating objects simply for information is to provide finer-grained methods which return information as primitives. This swaps object creation for increased method calls.
- A second technique is to provide methods which accept dummy information objects that have their state overwritten to pass the information.
- A third technique is to provide immutable classes with mutable subclasses, by having state defined as
protected in the superclass, but with no public updators. The subclass provides public updators, hence making it mutable.
- Don't try to speed up the application if there is no performance problem.
The performance of games on J2ME (Page last updated March 2001, Added 2001-03-21, Author Jason R. Briggs). Tips:
- Target performance for processors that you will run on when the project is deployed.
- Implementing the ImageProducer interface and setting an image's pixels directly eliminates one or two steps in the MemoryImageSource option and seems to be about 10 percent to 20 percent faster on average.
- Raw frame rate display, without taking account of the time taken to draw an image, runs from 2 frames per second (fps) to 400 fps, depending on processor and JVM. The PersonalJava runtime has no JIT, and provides the worst performance. With a JIT it might be usable.
- [Article includes references to a number of hardware based Java implementations, i.e. Java enabled CPUs.]
Introductory level article on threading applets (Page last updated March 2001, Added 2001-03-21, Author Monica Pawlan). Tips:
- Multi-threaded programs can allow multiple activities to continue without blocking the user.
- Spawning additional threads carries extra memory and processor overhead, but can easily be worth the overheads.
- Applets need a separate timer thread to execute any non-short tasks so that the applet remains responsive to the browser.
- The volatile modifier requests the Java VM to always access the shared copy of the variable so the its most current value is always read. If two or more threads access a member variable, AND one or more threads might change that variable's value, AND ALL of the threads do not use synchronization (methods or blocks) to read and/or write the value, then that member variable must be declared volatile to ensure all threads see the changed value.
Speeding up file searching in JFileChooser (Page last updated February 2001, Added 2001-03-21, Author Slav Boleslawski). Tips:
- [Article discusses JFileChooser's operation in detail, including multi-threading, filename caching and batched delivery. Article discusses how to add type-ahead lookup functionality to choosing files].
Using a ternary search tree for fast searches of partial text matches (Page last updated February 2001, Added 2001-03-21, Author Wally Flint). Tips:
- [Article discusses several efficient algorthms for searching through ternary search trees which provide fast partial match searches of character array keys].
JDBC Performance Tips (targetted at AS/400, but generically applicable) (Page last updated February 2001, Added 2001-03-21, Authors Richard Dettinger and Mark Megerian). Tips:
- Move to the latest releases of Java as they become available.
- Use prepared statements (PreparedStatement class) [article provides coded example of using Statement vs. PreparedStatement].
- Note that two database calls are made for each row in a ResultSet: one to describe the column, the second to tell the db where to put the data. PreparedStatements make the description calls at construction time, Statements make them on every execution.
- Avoid retrieving unnecessary columns: don't use "SELECT *".
- If you are not using stored procedures or triggers, turn off autocommit. All transaction levels operate faster with autocommit turned off, and doing this means you must code commits. Coding commits while leaving autocommit on will result in extra commits being done for every db operation.
- Use the appropriate transaction level. Increasing performance costs for transaction levels are: TRANSACTION_NONE; TRANSACTION_READ_UNCOMMITTED; TRANSACTION_READ_COMMITTED; TRANSACTION_REPEATABLE_READ; TRANSACTION_SERIALIZABLE. Note that TRANSACTION_NONE, with autocommit set to true gives access to triggers, stored procedures, and large object columns.
- Store string and char data as Unicode (two-byte characters) in the database.
- Avoid expensive database query functions such as: getBestRowIdentifier; getColumns; getCrossReference; getExportedKeys; getImportedKeys; getPrimaryKeys; getTables; getVersionColumns.
- Use connection pooling, either explicitly with your own implementation, or implicitly via a product that supports connection pooling.
- Use blocked fetchs (fetching table data in blocks), and tailor the block size to reduce calls to the database, according to the amount of data required.
- Use batch updates (sending multiple rows to the database in one call).
- Use stored procedures where appropriate. These benefit by reducing JDBC complexity, are faster as they use static SQL, and move execution to the server and potentially reduce network trips.
- Use the type-correct get() method, rather than getObject().
JDK 1.4 features update (Page last updated March 2001, Added 2001-03-21, Author Vinay Aggarwal). Tips:
- New standardized logging API.
- JDBC 3.0 includes connection pooling, connection pool configurations, reuse of prepared statements with connection pools, multiple open result sets on a statement, distributed transactions, CachedRowSets, and hooks to insert custom reader/writer classes.
- Assertions with new
- RMI support for customized remote objects and custom communications.
- Class reloading without customized classloaders.
- Scalable I/O including asynchronous requests and [presumably efficient] polling.
- 64-bit support in the JVM, class sharing across JVMs, faster classloading.
- Faster rendering in Java 2D, smaller jar files.
Weblogic tuning (generally applicable Java tips extracted) (Page last updated June 2000, Added 2001-03-21, Author BEA Systems). Tips:
- Response time is affected by: contention and wait times, particularly for shared resources; and software and hardware component performance, i.e. the amount of time that resources are needed.
- A well-designed application can increase performance by simply adding more resources (for instance, an extra server).
- Use clustered or multi-processing machines; use a JIT-enabled JVM; use Java 2 rather than JDK 1.1;
- Use -noclassgc. Use the maximum possible heap size that also is small enough to avoid the JVM from swapping (e.g. 80% of RAM left over after other required processes). Consider starting with minimum initial heap size so that the garbage collector doesn't suddenly encounter a full heap with lots of garbage. Benchmarkers sometimes like to set the heap as high as possible to completely avoid GC for the duration of the benchmark.
- Distributing the application over several server JVMs means that GC impact will be spread in time, i.e. the various JVMs will most likely GC at different times from each.
- On Java 1.1 the most effective heap size is that which limits the longest GC incurred pause to the longest acceptable pause in processing time. This will typically require a reduction in the maximum heap size.
- Too many threads causes too much context switching. Too few threads may underutilize the system. If n=number of threads, k=number of CPUs, then: (n < k) results in an under utilized CPU; (n == k) is theoretically ideal, but each CPU will probably be under utilized; (n > k) by a "moderate amount of threads" is practically ideal; (n > k) by "many threads" can lead to significant performance degradation from context switching. Blocked threads count for less in the previous formulae.
- Symptoms of too few threads: CPU is waiting to do work, but there is work that could be done; Can not get 100% CPU; All threads are blocked [on i/o] and runnable when you do an execution snapshot.
- Symptoms of too many threads: An execution snapshot shows that there is a lot of context switching going on in your JVM; Your performance increases as you decrease the number of threads.
- If many client connections are dropped or refused, the TCP listen queue may be too short.
- Try to avoid excessive cycling (creation/deletion or activation/passivation) of beans.
Weblogic JDBC tuning (Page last updated April 1999, Added 2001-03-21, Author BEA Systems). Tips:
- Use connection pools to the database. Optimal pool size is when the connection pool is just large enough to service requests without waits.
- Cache frequently requested data in the JVM and avoid the unnecessary database requests.
- Use zip files to download classes all together to an applet.
- Avoid accessing the database wherever possible.
- Pre-fetch rows in batches. Tune the number of rows pre-fetched. Avoid pre-fetching BLOBs.
- Avoid moving data unless absolutely necessary. Process the data and produce results as close to its source as possible. Use stored procedures.
- Use set processing, not row at a time processing. Process multiple rows together wherever possible.
- Counting entries in a table (e.g. using
SELECT count(*) from myTable, yourTable where ... ) is resource intensive. Try first selecting into temporary tables, returning only the count, and then sending a refined second query to return only a subset of the rows in the temporary table.
- Proper use of SQL can reduce resource requirements. Use queries which return the minimum of data needed: avoid
SELECT * queries. A complex query that returns a small subset of data is more efficient than a simple query that returns more data than is needed.
- Try to batch updates: collect statements together and execute them together in one transaction. Use conditional logic and temporary if necessary to achieve statement batching.
- Never let a DBMS transaction span user input.
- Consider using optimistic locking. Optimistic locking employs timestamps to verify that data has not been changed by another user, otherwise the transaction fails.
- Use in-place updates. Try to avoid moving rows or changing their sizes.
- Store operational data and historic data separately (or more generally store frequently used data separately from infrequently used data).
- DBMSs work well with parallelism. Try to design the application to do other things while interacting with the DBMS.
- Choose the fastest JDBC driver.
Weblogic's RMI framework (Page last updated January 1999, Added 2001-03-21, Author BEA Systems). Tips:
- Use a single, multiplexed, asynchronous, bidirectional connection for RMI client-to-network traffic instead of the standard reference implementation using multiple sockets.
- Try to improve the serialization mechanism for faster RMI [Externalization is better].
- Use local calls for objects located in the same JVM.
- Minimize distributed garbage collection.
- Use smart stubs which provide data caching and localized execution in addition to the normal remote execution and data fetching capabilities.
Basic performance tuning intro (Page last updated March 2000, Added 2001-03-21, Author Reggie Hutcherson). Tips:
- Use a JIT-enabled JVM or HotSpot.
Last Updated: 2017-10-01
Copyright © 2000-2017 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