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 ...
Newsletter no. 11, October 25th, 2001
JProfiler
|
Get rid of your performance problems and memory leaks!
|
JProfiler
|
Get rid of your performance problems and memory leaks!
|
|
|
I've extracted the tips from last month's articles together
with this months, so there's rather a lot of tips in this
month's newsletter, especially since the number of pages
coming out with performance related information seems to
increase every month. And my backlog of pages older than
six months just grows too (I'll add them one day, I
promise).
One interesting trend is the number of articles about
features new to the 1.4 SDK release, especially the java.nio
packages. Also J2EE performance seems to be a predominant
feature in many of the articles, no doubt reflecting the
amount of money currently being poured into that area of
Java, together with the strong crop of books focusing
on J2EE/EJB design patterns due out now.
Kirk is back, or rather Kirk's roundup is back. Kirk
himself is rather more forward than back. He's currently
finding that European I.T. has had rather less of a downturn
than the US, which is perhaps unsurprising as it never had
quite as strong an upturn in the first place.
And here's my usual reminder to our Japanese readers that
Yukio Andoh's translation should be available at
http://www.hatena.org/JavaPerformanceTuning/ in a while.
News
Java performance tuning related news.
Recent Articles
All the following page references have their tips extracted below.
(Articles listed in last month's
newsletter also have their tips extracted below.)
Links
Tools
Upcoming
Jack Shirazi
The reward for being a road warrior is that I get to visit airports.
Though some might dread the trip through the airport, I?ve used the
experience to compare how efficiently each of the different designs
has solved the problem of moving vehicles, aircraft, luggage, and
people. The most interesting aspects are the interfaces that allow
traffic to flow between each of the subsystems.
Consider the different sections of the airport that you moved through
on your last trip. In just about every airport that I?ve seen, the
roadways quickly divide vehicles into one of two groups, those picking
up, and those dropping off people. The building is designed to handle
this by separating those people departing from those who have just
arrived. Inside the building, there is typically a subsystem to handle
the three different groups of people who are arriving. At its core is
a secured area. Entry to this secured area depends upon where you?re
coming from. The more interesting aspect is that people and luggage
arriving from International destinations must be vetted before they can
be allowed to mix with the general population.
How do I measure efficiency in these systems? I use the old standard of
wall clock time to measure two primary use cases. These use cases are:
how long does it take for me to get onto a plane after I arrive at an
airport; and more importantly, how long does it take me to leave the
airport once my flight has arrived. Those of you who are lucky enough to
be going to the Olympics this year will be happy to know that I would
rate Salt Lake City as one of the most efficient airports in the world.
From The Middleware company, proving that sometimes the simplest
answers are best, a question regarding a 1.3 VM
running on Solaris which was GCing very 15 seconds. The response was a URL to
the Sun reference for HotSpot,
http://java.sun.com/docs/hotspot/gc/.
Ever since the arrival of the EJB spec, there have been questions about its
performance. Should one use Container Managed Persistence or Bean Managed
Persistence; Entity Beans or only Session Beans? Once again, this
question of EJB system architecture was raised at The Server Side. One
of the options listed was to use stateless Session Beans over data objects.
The consensus was that this mix offered the best chance for performance and
scalability. This post supports the current trend to remove Entity Beans from
existing systems that are not meeting performance requirements. My recent
experience was to recommend that Entity Beans be removed from one such
system. It was calculated that there would be an 80% reduction in the number
of objects created by the system if Entity Beans were dropped. These types
of reductions in object life cycle management are needed if the system is to
stand a chance of meeting its performance and stability requirements.
Javaranch included an interesting discussion on how to performance
tune an application that needed to deal with a ResultSet containing
40K Integers. In addition to the interesting interaction that
occurred between the moderators and the person who posed the question,
there were some useful clues given on how Vectors, ArrayList and other
collections grow. In short, it pays to pre-grow your collections.
Another thread saw a participant post a URL to a site containing
performance tips. The consensus was that the information on the
site, http://www.glenmccl.com/, though interesting was somewhat dated.
Though some performance tuning axioms never change, many are a result
of the current environment. The push for performance demands that
we understand the current environment.
The performance cost of import statements was again queried. Why
does no-one ever read earlier threads? Why doesn't the moderator
(or someone else) point the message to earlier threads? The answer
hasn't changed: there is no runtime cost to import, it is a compiler
directive and doesn't exist in the compiled bytecode.
An interesting question was about the difference between the following
two calls:
Class stringClass = "".getClass(); //1
Class stringClass = String.class; //2
The original poster was concerned with code size (his overriding
concern in an MIDP environment). The second call was 419 bytes more than
the first, because it generates a static method which is called for
each invocation. Other posters found that the second call was significantly
faster to run than the first, mainly because it consisted of a three
static instruction sequence at runtime, whereas the first call required a
dynamic lookup and getClass() invocation. Speed favors line 2, size favors
line 1. And of course if you require the class object more than once,
you should cache it (for optimal speed):
static Class StringClass = String.class;
Finally, an interesting discussion on reusing StringBuffers: it is a good
idea, but watch out for the gotcha where the StringBuffer has a larger
internal array than is necessary - all the subsequent resulting Strings
using that StringBuffer will also have the same larger internal array
than is necessary.
At JavaGaming, performance discussions often crop up outside
the main performance forum. Unsurprising really, a badly
performing game is unplayable. In the networking forum a whole
slew of discussions concerned the performance advantage of
Extenalizable. The conclusion was that you shouldn't use
Externalizable unless absolutely necessary - and in the case
of scaled up RMI applications it was absolutely necessary. The
discussions also talked about TCP vs UDP. The upshot here was
that if you need reliable delivery use TCP, otherwise UDP is
faster: implementing your own reliable deliery mechanism while
using UDP is a bit pointless.
Back in the performance forum, the -Xincgc crops up several times.
The -Xincgc option smooths garbage collection by running more often,
but actually takes more CPU resources. Use it if individual GC pause
time is more important than overall GC time.
And the last discussion I'm covering concerns drawing images
with affine transformations (scaling, rotating, etc). drawImage()
with an affine transformation creates temporary images (i.e.
garbage). The advice given was that pre-transformed images
should be reused to avoid generating garbage in the drawing
loop.
Kirk Pepperdine.
http://www.onjava.com/pub/a/onjava/2001/09/25/optimization.html
Multiprocess JVMs (Page last updated September 2001, Added 2001-10-22, Author Jack Shirazi). Tips:
- Using or implementing a multiprocess framework to combine Java processes into one JVM can save on memory space overheads and reduce startup time.
http://www.javaworld.com/javaworld/jw-10-2001/jw-1012-deadlock.html
Avoiding synchronization deadlocks (Page last updated October 2001, Added 2001-10-22, Author Brain Goetz). Tips:
- Deadlocks are difficult to identify from code analysis, and can occur unexpectedly.
- Always acquire locks in the same order to avoid one common cause of deadlocking. If you can guarantee that all locks will always be acquired in a consistent order, then your program will not deadlock.
- Try to avoid acquiring more than one lock at a time (though this is usually impractical).
- Keep synchronized blocks of code as short as possible.
http://www.sys-con.com/java/article.cfm?id=1165
The facade pattern for internationalization (Page last updated October 2001, Added 2001-10-22, Author David Gallardo). Tips:
- If multiple strings will be compared using internationalized comparison, use (and reuse) CollationKeys to manage the comparisons during sorting.
http://www-106.ibm.com/developerworks/ibm/library/i-tuning/?open
Tuning the IBM JVM and Linux (Page last updated May 2001, Added 2001-10-22, Authors Duc Vianney and James Phelan). Tips:
- [Article also has detailed coverage of tuning Linux].
- Use the -Xms and -Xmx parameters to set the heap size.
- Use -verbosegc to measure garbage collection statistics.
- Keep heap size smaller than physical memory.
- Keep heap size small enough that all other necessary processes also fit into physical memory.
- The IBM JVM has extra options to control JVM< heap size expansion and shrinkage.
- Use -Xrunhprof to profile the application [article gives and example of using -Xrunhprof to tune].
- Use local variables where possible.
- Use int instead of long.
- Use arrays instead of vectors.
- Use primitive types such as int and double instead of objects.
- Use exceptions only when necessary.
- Reuse objects as much as possible.
- Avoid writing to the console.
- Cache frequently used objects whenever possible.
- Declare methods as final. Classes and methods that aren't going to be redefined should be declared as final.
- Declare constants as static final.
- Limit the use of synchronized methods.
- Null old object references.
- Cache with soft references.
- Cache information that will be reused and is expensive to generate.
- Use jar files.
http://developer.java.sun.com/developer/qow/archive/153/index.jsp
Minimizing space taken by HTTP downloads (Page last updated October 2001, Added 2001-10-22, Authors Gary Adams and Eric Giguere). Tips:
- Use HttpConnection.getLength() to determine the number of bytes needed to to hold the data from a download.
- Use a ByteArrayOutputStream to accumulate results if the content length is indeterminate.
- The best performance is obtained from a 1.1 compliant webserver using persistent connections.
http://developer.java.sun.com/developer/Books/J2EETech/ch3.pdf
Rambling discussion of building J.Crew website, in Chapter 3 of "J2EE Technology in Practice" (Page last updated September 2001, Added 2001-10-22, Authors Dao Ren, Dr. Rick Cattell and Jim Inscore). Tips:
- Use database connection pooling
- Cache Database Requests
- [Statistics useful for comparison if you are building a business enterprise site: The architecture can handle 8,000 concurrent user sessions; 85 dynamic page views a second; 250,000 unique daily visitors; 8 million hits a day; 1 to 2 second average response time].
http://developer.java.sun.com/developer/JDCTechTips/2001/tt0925.html
Generating integer random numbers (Page last updated September 2001, Added 2001-10-22, Author John Zukowski). Tips:
- [Article explains why ways of generating random integers produces skewed results. Important for correctly simulating a variety of things].
http://www.javaworld.com/javaworld/javaqa/2001-09/02-qa-0921-double.html
String to double (Page last updated September 2001, Added 2001-10-22, Author Tony Sintes). Tips:
- Use
Double.parseDouble()
instead of Double.valueOf(aString).doublevalue()
.
http://www.owlmountain.com/tutorials/NonBlockingIo.htm
Tutorial on non-blocking socket I/O available from JDK 1.4 (Page last updated September 2001, Added 2001-10-22, Author Tim Burns). Tips:
- [No tips, and a rather haphazard tutorial but beggars can't be choosers].
http://developer.java.sun.com/developer/technicalArticles/releases/nio/
The java.nio packages (Page last updated October 2001, Added 2001-10-22, Author John Zukowski). Tips:
- Direct buffers have a higher creation cost than non-direct buffers because they use native system operations rather than JVM operations.
- Reduce threads by multiplexing I/O using selectors.
http://www.sys-con.com/java/article.cfm?id=1169
Javabean component architecture (Page last updated October 2001, Added 2001-10-22, Authors David Hardin and Mike Frerking). Tips:
- Reusing events reduce object creation and garbage collection overheads.
- Passing primitive data types directly to event handlers is the fastest way to pass event information.
- Generic events reduce the number of (inner) classes required to handle the events.
http://developer.java.sun.com/developer/technicalArticles/Using/
The logging APIs (Page last updated September 2001, Added 2001-10-22, Author Tom Harpin). Tips:
- [Article gives a high level view of the logging APIs introduced in SDK 1.4. No application is adequately deployed unless it has some performance logging in place].
- Formatting of log records is separate from the generation and transfer of the records, so that the formatting overhead is incurred only on demand (and possibly asynchronously).
http://www.sys-con.com/java/article.cfm?id=1160
Local entity beans (Page last updated October 2001, Added 2001-10-22, Author Alex Pestrikov). Tips:
- Local entity beans do not need to be marshalled, and do not incur any marshalling overhead for method calls either: parameters are passed by reference.
- Local entity beans are an optimization for beans which it is known will be on the same JVM with their callers.
- Facade objects (wrappers) allow local entity beans to be called remotely. This pattern incurs very little overhead for remote calls, while at the same time optimizing local calls between local beans which can use local calls.
http://www.sys-con.com/java/article.cfm?id=1171
J2EE Performance tuning (Page last updated October 2001, Added 2001-10-22, Author James McGovern). Tips:
- Call HttpSession.invalidate() to clean up a session when you no longer need to use it.
- For Web pages that don't require session tracking, save resources by turning off automatic session creation using: <%@ page session="false"%>
- Implement the HttpSessionBindingListener for all beans that are scoped as session interface and explicitly release resources implementing the method valueUnbound().
- Timeout sessions more quickly by setting the timeout or using session.setMaxInactiveInterval().
- Keep-Alive may be extra overhead for dynamic sites.
- Use the include directive <%@ include file="copyleft.html" %> where possible, as this is a compile-time directive (include action <jsp:include page="copyleft.jsp" /> is a runtime directive).
- Use cache tagging where possible.
- Always access entity beans from session beans.
- If only using an entity bean for data access, use JDBC directly instead.
- Use read-only in the deployment descriptor.
- Cache access to EJB homes.
- Use local entity beans when beans are co-located in the same JVM.
- Proprietary stubs can be used for caching and batching data.
- Use a dedicated remote object to generate unique primary keys.
- Follow standard JDBC optimizations: use connection pools; prefer stored procedures or direct SQL; use type 4 drivers; remove extra columns from the result set; use prepared statements when practical; have your DBA tune the query; choose the appropriate transaction levels.
- Consider storing all database character data in Unicode to eliminate conversion overheads. But beware: this step will cause your database size to grow, as Unicode requires 2 bytes per character.
- Use block fetches when the query will give a large ResultSet and all rows are needed. Use the Page-by-Page Iterator pattern when only some of the rows may be needed.
- Consider using an in-memory database (product) for data that doesn't need to be persisted.
- Use an algorithm to prune caches to stop them growing too large.
- Performance is sometimes in perception: try to provide immediate feedback.
- Optimizing code is one of the last things developers should consider.
http://developer.java.sun.com/developer/Books/EarlyJ2SE/IO.pdf
Shortened version of chapter 2, "I/O", from "Early Adopter J2SE 1.4" (Page last updated October 2001, Added 2001-10-22, Author James Hart). Tips:
- Non-blocking I/O can improve performance by minimizing the amount of time spent in I/O calls, though they may add complexity to the application.
- The old I/O classes can now be interrupted more reliably from 1.4.
- FileChannel.transferFrom() is an efficient way to copy data between files.
http://developer.java.sun.com/developer/Books/EarlyJ2SE/Using.pdf
Shortened version of chapter 5, "Utilities: The Logging Architecture", from "Early Adopter J2SE 1.4" (Page last updated October 2001, Added 2001-10-22, Author James Hart). Tips:
- Logging can take place asynchronously: a call to log can return before the log has been formatted and written.
- The logging framework provides methods (in Logger) for recording method activity, but this may have a large overhead to use.
http://www.onjava.com/pub/a/onjava/2001/09/26/load.html
Load Balancing Web Applications (Page last updated September 2001, Added 2001-10-22, Author Vivek Veek). Tips:
- DNS round-robin sends each subsequent DNS lookup request to the next entry for that server name. This provides a simple machine-level load-balancing mechanism, but is only appropriate for session independent or shared-session servers.
- DNS round-robin has no server load measuring mechanisms, so requests can still go to overloaded servers, i.e. the load balancing can be very unbalanced.
- Hardware load-balancers solve many of the problems of DNS round-robin, but introduce a single point of failure.
- A web server proxy can also provide load-balancing by redirecting requests to multiple backend webservers.
http://win-www.uia.ac.be/~s985218/professional/thesis/archief/documenten/Marktoverzicht.doc
Overview of common application servers (announced at http://www.theserverside.com/home/thread.jsp?thread_id=9581). I've extracted the performance related features (Page last updated October 2001, Added 2001-10-22, Author Pieter Van Gorp ). Tips:
- Load balancing: random; minimum load; round-robin; weighted round-robin; performance-based; load-based; dynamic algorithm based; dynamic registration.
- Clustering. Additionally: distributed transaction management; in-memory replication of session state information; no single point of failure.
- Connection pooling.
- Caching. JNDI caching. Distributed caching with synchronization.
- Thread pooling.
- Configurable user Quality of Service.
- Analysis tools.
- Low system/memory requirements.
- Optimized subsystems (RMI, JMS, JDBC drivers, JSP tags & cacheable page fragments).
- Optimistic transaction support.
Tips II (from last month's newsletter)
http://www.onjava.com/pub/a/onjava/2001/08/22/optimization.html
Catching OutOfMemoryErrors (Page last updated August 2001, Added 2001-10-22, Author Jack Shirazi). Tips:
- -Xmx and -Xms (-mx and -ms) specify the heap max and starting sizes. Runtime.totalMemory() gives the current process size, Runtime.maxMemory() (available from SDK 1.4) gives the -Xmx value.
- Repeatedly allocating memory by creating objects and holding onto them will expand the process to its maximum possible size. This technique can also be used to flush memory.
- If a process gets too large, the operating system will start paging the process causing a severe decrease in performance.
- It is reasonable to catch the OutOfMemoryError if you can restore your application to a known state that can proceed with processing. For example, daemon service threads can often do this.
http://java.oreilly.com/news/javaxslt_0801.html
Tips on using XSLT (Page last updated August 2001, Added 2001-10-22, Author Eric M. Burke). Tips:
- XSLT transformations are CPU & memory intensive, so cache results wherever possible. Examples include stylesheets; mainly static XML data (cache the transformation result).
http://www.onjava.com/pub/a/onjava/2001/09/18/jboss.html
Implementing clustering on a J2EE web server (JBoss+Jetty) (Page last updated September 2001, Added 2001-10-22, Author Bill Burke). Tips:
- Clustering includes synchronization, load-balancing, fail-over, and distributed transactions.
- [article discusses implementing clustering in an environment where clustering was not previously present].
- The different EJB commit options affect database traffic and performance. Option 'A' (read-only local caching) has the smallest overhead.
- Hardware load balancers are a simple and fast solution to distributing HTTP requests to clustered servers.
http://developer.java.sun.com/developer/J2METechTips/2001/tt0917.html
Making HTTP connections using background threads. (Page last updated September 2001, Added 2001-10-22, Author Eric Giguere). Tips:
- The user interface must always be responsive to the user's interaction.
- The application should respond to input no later than a tenth of a second after it occurs: longer delays are noticed by the user, and make the user interface seem unresponsive. So don't do more than about a tenth of a second's worth of work in the user-service thread in response to any user interface event.
- Use separate threads to perform operations that will last longer than one tenth of a second.
- Provide the user with the option to cancel the operation at any time.
- [Article provides an example of making an HTTP connection following these suggestions].
http://www.theserverside.com/resources/article.jsp?l=Is-EJB-Appropriate
Deciding whether EJB is appropriate. (Page last updated September 2001, Added 2001-10-22, Author Ed Roman). Tips:
- An HTTP layer is not always necessary. Connecting directly to EJBs is faster and provides automatic load balancing.
http://www.javaworld.com/javaworld/jw-09-2001/jw-0907-merlin.html
Using nonblocking I/O and memory-mapped buffers in SDK 1.4. (Page last updated September 2001, Added 2001-10-22, Author Michael T. Nygard). Tips:
- Before SDK 1.4, servers had a number of perormance problems: i/o could easily be blocked; garbage was easily generated when reading i/o; many threads are needed to scale the server.
- Many threads each blocked on i/o is an inefficient architecture in comparison to one thread blocked on many i/o calls (multiplexed i/o).
- Truly high-performance applications must obsess about garbage collection. The more garbage generated, the lower the application throughput.
- A Buffer (java.nio.*Buffer) is a reusable portion of memory. A MappedByteBuffer can map a portion of a file directly into memory.
- Direct Buffer objects can be read/written directly from Channels, but nondirect Buffer objects have a data copy performed for read/writes to i/o (and so are slower and may generate garbage). Convert nondirect Buffers to direct Buffers if they will be used more than once.
- Scatter/gather operations allow i/o to operate to and from several Buffers in one operation, for increased efficiency. Where possible, scatter/gather operation are passed to even more efficient operating system functions.
- Channels can be configured to operate blocking or non-blocking i/o.
- Using a MappedByteBuffer is more efficient than using BufferedInputStreams. The operating system can page into memory more efficiently than BufferedInputStream can do a block read.
- Use Selectors to multiplex i/o and avoid having to block multiple threads waiting on i/o.
http://www.javaworld.com/jw-09-2001/jw-0907-rmi.html
RMI performance tuning (Page last updated September 2001, Added 2001-10-22, Author Ashok Mathew and Mark Roulo). Tips:
- Use netperf to measure network bandwidth.
- Consider altering the TcpWindowSize parameter.
- Configure RMI garbage collection by setting the properties
sun.rmi.dgc.client.gcInterval
and sun.rmi.dgc.server.gcInterval
.
- Send groups of objects together rather than one object at a time.
- Implementing
Externalize
can speed up transfers.
- Pack data to reduce the number and amount of reads and writes, and the amount of data transferred.
- Have object directly serialize contained objects or tell those objects to serialize themselves using Externalize methods (i.e. chain Externalize methods for all contained objects).
- Use special codes to handle special cases such as singleton or reusable objects.
- Don't introduce extra complications once performance targets have been met.
http://developer.java.sun.com/developer/technicalArticles/Threads/swing/
Multithreaded Swing Applications (Page last updated September 2001, Added 2001-10-22, Author Monica Pawlan). Tips:
- Use the SwingUtilities.invokeAndWait() and SwingUtilities.invokeLater() methods to put code on the GUI event queue.
- Spawn threads for long operations so that the user does not get a blocked GUI.
http://www.microjava.com/articles/techtalk/display?PageNo=1
Timers and low-level GUI display effects (Page last updated September 2001, Added 2001-10-22, Author Roman Bialach). Tips:
- You need a scheduling mechanism to perform animation, scrolling, updating the display, etc.
- The paint() method on the Canvas is called by the system only if it thinks that it needs to repaint it. So we need another timer to repaint the screen on a regular basis. Use a timer to periodically call repaint().
http://www.javareport.com/html/from_pages/article.asp?id=4702&mon=9&yr=2001
Architecting and Designing Scalable, Multitier Systems (Page last updated August 2001, Added 2001-10-22, Author Michael Minh Nguyen). Tips:
- Separate the UI controller logic from the servlet business logic, and let the controllers be mobile so they can execute on the client if possible.
- Validate data as close to the data entry point as possible, preferably on the client. This reduces the network and server load. Business workflow rules should be on the server (or further back than the front-end).
- You can use invisible applets in a browser to validate data on the client.
http://www.theserverside.com/resources/articles/JSP-Performance/ProJsp.html
Performance chapter (chapter 20) from "Professional JSP 2nd Edition" (Page last updated August 2001, Added 2001-10-22, Author Simon Brown, Robert Burdick, Darko Cokor, Jayson Falkner, Ben Galbraith, RodJohnson, Larry Kim, Casey Kochmer, Thor Kristmundsson, Sing Li, Dan Malks, Mark Nelson, Grant Palmer, Bob Sullivan, Geoff Taylor, John Timney, Sameer Tyagi, Geert Van Damme, Steve Wilkinson). Tips:
- The user's view of the response time for a page view in his browser depends on download speed and on the complexity of the page. e.g. the number of graphics. A poorly-designed highly graphical dynamic website could be seen as 'slow' even if the web downloads are individually quite fast.
- No web application can handle an unlimited number of requests; the trick in optimization is to anticipate the likely user demand and ensure that the web site can gracefully scale up to the demand while maintaining acceptable levels of speed.
- Profile the server to identify the bottlenecks. Note that profiling can be done by instrumenting the code with measurement calls if a profiler is unavailable.
- One stress test methodology is: determine the maximum acceptable response time for getting a page; estimate the maximum number of simultaneous users; simulate user requests, gradually adding simulated users until the web application response delay becomes greater than the acceptable response time; optimize until you reach the desired number of users.
- Pay special attention to refused connections during your stress test: these indicate the servlet is overwhelmed.
- There is little performance penalty to using an MVC architecture.
- Use resource pools for expensive resources (like database connections).
- Static pages are much faster than dynamic pages where the web server can handle static pages separately.
- Servlet filtering has a performance cost. Test to see if it is an acceptable cost.
- Ensure that the webserver is configured to handle the expected number of user for example: enough ready sockets; enough disk space; enough CPU.
- Use the fastest JVM you have access to.
http://www-106.ibm.com/developerworks/java/library/j-threads2.html
Reducing thread contention (Page last updated September 2001, Added 2001-10-22, Author Brian Goetz). Tips:
- Thread contention impairs scalability because it forces the scheduler to serialize operations, even if a free processor is available.
- Analyze your program to determine where contention is likely to occur.
- Make synchronized blocks as short as possible.
- Spread synchronizations over more than one lock.
- [Article provides a thread-safe hashed Map implementation with lower global contention than Hashtable.]
- If you will be acquiring and releasing the same lock many times (such as in a loop), acquire the lock before the loop: it is faster to acquire a lock that you already hold than one that nobody holds.
http://www.sys-con.com/java/article.cfm?id=1149
Performance tuning (Page last updated September 2001, Added 2001-10-22, Author James McGovern). Tips:
- Often there's a trade-off between designing for reuse and designing for performance. Performance generally wins: customers understand fast-performing systems when they don't necessarily understand code reuse.
- Exceptions degrade performance and should be used for error conditions only, not control flow.
- Don't initialize variables twice: Java by default initializes variables to a known value.
- Use the factory pattern to enable reuse or cloning of objects.
- Make classes final.
- Use local variables as much as possible.
- Use non-blocking I/O (available from 1.4, or use www.cs.berkeley.edu/~mdw/proj/java-nbio/download.html for earlier versions).
- Create/Use method interfaces that reduce overhead.
- Use bit-shifting instead of multiplication or division by powers of two.
- Choose the JVM that runs your application fastest.
- Use clustering application servers.
- Avoid stateful sessions.
- Profile and tune the application (architecture and code).
- Set aside at least 20% of the total project time for performance.
- Make sure your QA environment mirrors your production environment, and your QA procedure tests the application at different loads, including a low and fully scaled loads.
http://www.sys-con.com/java/article.cfm?id=1133
Techniques to avoid deadlocks (Page last updated September 2001, Added 2001-10-22, Author Mark Dykstra). Tips:
- Potential deadlocks can be caused by coding styles.
- Always acquire a set of locks in the same set order.
- Don't hold a lock and wait for an event.
- Specify which thread should have access to data at any time.
- Ensure that both access and update to the same variable is synchronized on the same monitor.
http://www.ddj.com/articles/2001/0109/0109a/0109a.htm
Developing Scalable Distributed Applications (Page last updated August 2001, Added 2001-10-22, Author Mario A. Torres). Tips:
http://www.javaworld.com/javaworld/javaqa/2001-08/01-qa-0817-static.html
Inner classes (Page last updated August 2001, Added 2001-10-22, Author Tony Sintes). Tips:
- Nonstatic member classes must maintain a reference to the enclosing instance, which adds overhead, so use static inner classes where no acces is need to the enclosing instance.
http://discuss.develop.com/archives/wa.exe?A2=ind0010A&L=DOTNET&P=R28572
Microsoft discussion about csharp garbage collection (the Java clone unsurprisingly has similar issues) (Page last updated October 2001, Added 2001-10-22, Author Brian Harry). Tips:
- [No performance tips here. But a fascinating discussion about all the thought that has gone in to csharp GC, only to result in a what already exists in Java].
http://www.sys-con.com/java/article.cfm?id=1135
J2EE design optimizations (Page last updated September 2001, Added 2001-10-22, Author Vijay S. Ramachandran). Tips:
- For data that changes infrequently (i.e. rarely enough that a user session will not need that data updating during the session lifetime), avoid transactional access by using a cached Data Access Object rather than the transactional EJB (this is called the Fast Lane Reader pattern).
- Don't transfer long lists of data to the user, transfer a page at a time (this is called the Page-by-Page Iterator pattern).
- Instead of making lots of remote requests for data attributes of an object, combine the attributes into another object and send the object to the client. Then the attributes can be queried efficiently locally (this is called the Value Object pattern). Consider caching the value objects where appropriate.
http://www.javaworld.com/jw-09-2001/jw-0914-access.html
Customized high-speed, fine-grained access control (Page last updated September 2001, Added 2001-10-22, Author Wally Flint). Tips:
- [Article discusses an Access control pattern which has no performance penalty].
Jack Shirazi
Last Updated: 2023-02-26
Copyright © 2000-2023 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/newsletter011.shtml
RSS Feed: http://www.JavaPerformanceTuning.com/newsletters.rss
Trouble with this page? Please contact us