Wait/notify and fat locks

Recall from the last chapter that wait and notify always inflates thin locks to fat locks in JRockit. Locks that are frequently taken and released, but are only held for a short time might do better as thin locks. So, immediately using wait or notify on a new object will create a new monitor and consequently a fat lock that might lead to performance overhead.

Wrong heap size

Another common problem that causes performance issues is using the wrong heap size for the JVM. Too small heaps trigger frequent and time consuming garbage collections. Too large heaps lead to longer mean GC times and may cause the JVM to run out of native memory. It makes sense to do profiling runs to figure out the memory requirements of your application and try to find an optimal maximum heap size. JRockit Mission Control will almost always provide good data on the memory requirements for a particular application.

Too much live data

As we have discussed in the chapter on garbage collection, the main contributor to runtime complexity in memory management is not the heap size per se, but rather the amount of live data on the heap. Large amounts of live data almost certainly create garbage collection overhead. Again, profiling can help figure out if there are any large object clusters kept in memory even though there shouldn't be.

The Memleak tool, which is part of the JRockit Mission Control suit is ideal for this kind of analysis.

Java is not a silver bullet

Finally, Java is a powerful and versatile language that contributes to short application development time because of its friendly semantics and built-in memory management. However, Java is not a silver bullet. The last caveat this chapter will warn of is trying to use Java to solve a problem that in fact is totally inappropriate for Java.

  • Is the application a telecom application with virtually tens of thousands of concurrent threads that need near-real-time support?
  • Does the application contain a database layer that frequently returns 20 MB query results of binary data in the form of byte arrays?
  • Is the application completely dependent on the underlying OS scheduler for performance and determinism, with bad overhead problems if the scheduling semantics change even slightly?
  • Is the application a device driver?
  • Has the development team implemented a C/Fortran/COBOL-to-Java automatic translator, so that those 100,000 lines of legacy code can "easily" be deployed on a modern Java runtime?
  • Is the program highly concurrent or embarrassingly parallel, that is, it tries to use a divide and conquer strategy that branches off tens of thousands of threads that run computations for a short period of time before fusing the partial results?

In these cases, and there are probably plenty of others, it might be considered doubtful if using Java is the correct approach. Java is highly attractive in that the JVM provides an abstract layer on top of the operating system and in that Java programs can be compiled once, and run everywhere. But, stretching it a bit, so can ANSI C. Just ship the source code and make sure it is portable. Choose your tool with care. Java is a lovely multi-purpose hammer, but not every problem is a nail!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.137.38