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 May 2007
Get rid of your performance problems and memory leaks!
Get rid of your performance problems and memory leaks!
Back to newsletter 078 contents
Su Doku Solving Efficiency (Page last updated May 2007, Added 2007-05-29, Author Jack Shirazi, Publisher Fasterj.com). Tips:
- Adding intelligence to a search can make it more efficient.
- The -Xprof profiler is sufficient to profile small or simple applications.
- A benchmark harness can interfere with a benchmark test, and this needs to be checked for.
- There are two types of common problems with benchmarks: code is not measuring what you think it is measuring (e.g. you forget to measure the cost of hotspot kicking in, or the harness is causing an issue); and the dataset is not appropriate or correct.
- A common reason for large applications using databases to have performance issues in production even where the functionality is fully tested in development - the test dataset used is often too small in critical areas.
How does Google Web Accelerator work? [included as a ref because it clearly identifies the basics of improving any distributed application] (Page last updated April 2007, Added 2007-05-29, Author Google, Publisher Google). Tips:
- Use machines & servers dedicated to handling the application.
- Cache copies of frequently accessed data to make them quickly accessible.
- Transfer only the changes to required data if specifying those changes are smaller than the full data set and has a reasonable processing cost.
- Prefetch data in advance.
- Optimize the connection to reduce delays.
- Compress data before sending it.
- Include monitoring in the various optimizations so that improvements and degradations can be measured (so determining the effectiveness of the techniques used).
Stack Trace 101 (Page last updated June 2004, Added 2007-05-29, Author shivane, Publisher shivane). Tips:
- A stack trace usually holds all the information needed to determine what caused that stack trace.
- [Article converts a stack trace into plain english].
- You can alter code to explicitly create exceptions to find where some event or action occurs.
- [Article gives an example of determining what is causing an explicit GC by adding exceptions to print stack traces to find the cause].
- The -XX:+DisableExplicitGC option prevents explicit GC calls (e.g. System.gc()) from causing a GC.
- When using RMI, sun.rmi.transport.ObjectTable triggers a regular full GC based on an interval specified by the system property sun.rmi.dgc.server.gcInterval.
- Creating exception objects is resource intensive. Creating too many exception objects takes lot of CPU.
- A full thread dump tells you what every single thread in the Java VM is doing at any given moment. You can get a thread dump by typing Ctrl+\ for unices or Ctrl+Break for windows machines. or also on unix, you could execute kill -SIGQUIT "pid".
- The thread dump output differs from version to version and from vendor to vendor, the basic structure is the same. Each thread is dumped separately with first line showing the thread name, daemon status, thread priority, thread run state, then come multiple lines showing the current stack in a normal stack trace.
- Taking a few full thread dumps at regular intervals provides a basic very low resolution profiler.
- If you have a high CPU consumption and poor response time and thread dumps show the same thread in the same method or same class then that method/class is the one which is definitely taking a lot of CPU - see if you can optimize these calls.
- If you have a low CPU consumption most of which is kernel time and poor response time and thread dumps show the runnable threads performing some IO operations then most likely your application is IO bound.
- If you notice that most IO operations are from the data base driver, see if you can reduce the number of queries to the database or see if you can cache the results of the query locally.
- If you have medium or low CPU consumption in a highly multithreaded application and most threads in most thread dumps are waiting for a monitor on the same object then you are contended - see if you can eliminate the need for synchronization (e.g. using ThreadLocal/Session-scope objects) or reduce the amount of code being executed within the synchronized block.
- If you have medium or low CPU consumption in a highly multithreaded application and most threads in most thread dumps are waiting for a resource, see if you can make that resource available more often, for example if you were waiting on a pool to create EJB-bean objects/DB Connection objects, see if you can increase the pool size for that resource.
- Full thread dumps produce a report at the end of the dump if any deadlocks exist.
- You can an artificial deadlock due to resource limitation which will not be reported as a deadlock, e.g. if a pool is used up and the current holders of the pool elements will not release any elements because they all need at least one more pool element to proceed.
- If an app is not responding and the CPU consumption is 0% (or very low), thread dumps should typically either show a deadlock, or threads waiting for resources that are exhausted - for the latter try increasing pool limits or decreasing the number of resources required within a transaction.
Tuning Derby (Page last updated January 2007, Added 2007-05-29, Author Dejan Bosanac, Publisher OnJava). Tips:
- There is a big difference in the performance of a database when it is populated with a small amount of test inputs and when it holds a large amount of data.
- Trying to read a large number of rows from a database can easily result in an OutOfMemoryError, so you need to be careful to page result sets
- To support paging of results, many database servers support specialized SQL constructs that can be used to retrieve a specified subset of query results. For example, in MySQL you'll find the LIMIT and OFFSET keywords, which can be used in SELECT queries, e.g. "select * from tbl LIMIT 50 OFFSET 100" will contain 50 rows starting from the 100th result in the result set.
- You should use the setMaxRows() method of the java.sql.Statement interface to avoid accessing rows that are not needed (i.e. if only accessing the first 100 rows, then setMaxRows(101)).
- Avoid table scans - make sure indexes are used. Use the query plan of the db server to determine if indexes are used (in Derby, use System.setProperty("derby.language.logQueryPlan", "true") which will log all executed queries in the derby.log file located in the derby.system.home folder).
- Sorting a result set on a non-indexed field is a common suspect for poor query performance.
- Note that if sorting in reverse order, you need to create a separate descending index on the field to avoid table scans.
- Over time, index pages can fragment, which can cause serious performance degradation. You should periodically drop and recreate the index, e.g. DROP INDEX tbl_field CREATE INDEX tbl_field ON tbl(field) CREATE INDEX tbl_field_desc ON tbl(field desc)
- For select statements where selection is qualified by a where clause on field1, but sorted on field2 (with no qualification on field2), you need to create an index that covers both fields, e.g. CREATE INDEX tbl_field1_field2 ON tbl(field1, field2) (column order is significant).
- Indexes improve performance when data selection is in question, but they slow down database insert, and delete and possibly update operations.
- Optimize database and application design according to your needs. Don't index every column; you might not use those indexes, and you might need to optimize your database for fast inserting of data.
- Measure your performance early and identify bottlenecks; only then should you try to tune.
- Caching data read from the db can lead to very effective performance improvements.
Unfreeze Your Applications with the New SwingWorker (Page last updated March 2007, Added 2007-05-29, Author Dan Andrews, Publisher Java Boutique). Tips:
- Poorly-written Swing applications can appear to freeze when time-consuming code is executing on the Swing event dispatch thread.
- Failure to provide users with feedback on the current execution can lead to a bad perception of performance.
- Execute long running code in a background thread by: spawning a thread from the user action; call SwingUtilities.invokeAndWait and invokeLater from the thread to update the user on action from that asynchronous thread.
- Java 6 includes a javax.swing.SwingWorker implementation as a reusable way to move time-consuming code to a background thread.
- SwingWorker makes use of Future for the tasks assigned to it, so these can be cancelled where possible; and property change listeners so that the task state can be monitored and reported.
- A SwingWorker tutorial has been added to the Sun Java tutorials at http://java.sun.com/docs/books/tutorial/uiswing/concurrency/worker.html
Programmatically dumping heap from Java applications (Page last updated May 2007, Added 2007-05-29, Author A. Sundararajan, Publisher Sun). Tips:
- You can use the jmap -dump option to dump heap dump of a running application.
- You can browse/analyze the Sun JVM binary heap dump format using the jhat tool.
- You can programmatically dump the heap from a Sun JVM using HotSpotDiagnosticMXBean.dumpHeap().
- The jmap tool uses object addresses as object identifiers - which vary between garbage collections (so correlating objects between dumps is not easy).
- You can start the VM with the option
-XX:+PrintClassHistogram. With that option, a heap histogram is printed whenever a SIGQUIT signal is sent to the process.
Obtaining and analyzing thread dumps (Page last updated May 2007, Added 2007-05-29, Author Bhakti Mehta, Publisher java.net). Tips:
- jstack prints Java stack traces of Java threads for a given Java process or core file or a remote debug server.
- Adaptj's Stacktrace lets you get a stacktrace from a Java process whether an applet, standalone, or in a server container.
- cntrl-break on Windows or cntrl-\ or kill -QUIT "pid" on Unix will dump the current stack
Back to newsletter 078 contents
Last Updated: 2021-04-28
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