Performance Zone is brought to you in partnership with:

As Director of Engineering, Bhaskar is responsible for leading the company's engineering processes. Prior to joining AppDynamics, Bhaskar was Lead Engineer at Wily Technology, where he pioneered a dynamic instrumentation engine as well as the company’s product expansion into .NET. Prior to that, he was Lead Engineer for Pramati Technologies, where he was one of the key people behind the design and development of their J2EE Application Server. Bhaskar received a B.S. degree in Computer Science and Engineering from Madras University. Bhaskar has posted 2 posts at DZone. View Full User Profile

Three Common Application Performance Challenges for Developers

12.22.2010
| 17977 views |
  • submit to reddit
Java is a great language. It manages memory for you, teaches us about object-oriented programming, and makes us better coders as we use it. Plus, it really is a ‘write once, run anywhere’ language. Nonetheless, Java applications can run into a few common performance challenges that developers and app owners should be familiar with:

Memory Leaks

One of the great benefits of Java is its ability to take care of the memory model for you. When objects aren’t in use, Java helps you out by doing the clean up. Older languages need you to do your memory management manually, but you would rather spend time focusing on core application logic than worrying about memory allocation.

Having said that, it’s not to say that Java memory management guarantees zero memory problems. By managing the memory model for you, or rather the creation/destroying of objects that are unused, Java puts them in a heap. Memory leaks typically happen as a result of improper programming – usually when the developer didn’t relieve all references to an object. Thus, your heap builds up and your app comes to a grinding halt.

Most people use heap dumps and/or profilers to diagnose memory leaks. A heap dump allows you to see which object is holding a reference to the collections. It gives you an idea of where the collection is, but doesn’t tell you who is accessing the collection or their characteristics to let you drill down to root cause. Heap dumps are also usually quite large, in gigabytes, and it takes significant resources to analyze and open a heap dump, then read it and identify the issue.

The second method, a combination of a heap dump and a profiler, gets you a little bit closer, but not much. Memory profilers try to help you analyze your heap dump. They have live data and now you know who is creating the objects, but you still don’t know what’s actually causing the leak.

Both heap dumps and profilers can be helpful in development and pre-production, but once your apps are out in the wild, profilers just aren’t useable. One of the most effective ways to isolate and address memory leaks is through transaction and code path analysis. By taking a snapshot of the transaction, you can get a better idea of where the issue is and who is causing it, which usually leads to less downtime and better MTTR.

Slow SQL

Almost every application uses a JDBC database. A very common problem with applications is badly performing SQL. This can be due to fields not being indexed, too much data being fetched, and other various problems. This affects application performance adversely because most applications use multiple SQL invocations per user request.

There could be many causes slow SQL.. But one in particular stands out: the Object Relational Mapper (ORM).

The ORM has become a method of choice for bringing together the two foundational technologies that we base business applications on today – object-oriented applications (Java, .NET) and relational databases (Oracle, mySQL, PostgreSQL, etc.). Most applications today use a relational database.  For many developers, this technology can eliminate the need to drill-down into the intricacies of how these two technologies interact.  However, ORMs can place an additional burden on applications, significantly impacting performance while everything looks fine on the surface.

In the majority of cases, the time and resources taken to retrieve data are orders of magnitude greater than what’s required to process it. It is no surprise that performance considerations should always include the means and ways of accessing and storing data.

While intuitive for an application developer to use (they do hide the translation complexities), an ORM can also be a significant weight on an application’s performance. Make sure you understand what’s going on under the hood.

Threading/Synchronization


Issues arising from synchronization are often hard to recognize and their impact on performance can become significant.

The fundamental need to synchronize lies with Java’s support for concurrency. This is implemented by allowing the execution of code by separate threads within the same process. Separate threads can share the same resources, objects in memory. While being a very efficient way to get more work done (while one thread waits for an IO operation to complete, another thread gets the CPU to run a computation), the application is also exposed to interference and consistency problems.

To prevent such a scenario programmers use the “synchronized” keyword in his/her program to force order on concurrent thread execution. Using “synchronized” prevents threads from obtaining the same object at the same time and prevents data inconsistencies.

In practice, however, this simple mechanism comes with substantial side effects. Modern business applications are typically highly multi-threaded. Many threads execute concurrently, and consequently “contend” heavily for shared objects. Synchronization effectively forces concurrent processing back into sequential execution.

There isn’t a silver bullet for addressing thread and synchronization issues today. Some developers rely on ‘defensive’ coding practices like locking, while others may rely on Software Transactional Memory Systems (STM) to help mitigate the issue. The best development organizations are the ones that can walk the fine line of balancing code review/rewrite burdens and concessions to performance.

--
These are just a few application performance issues Java developers face on a daily basis. There are a variety of helpful application performance tools and vendors out there that can help reduce these issues dramatically.


Published at DZone with permission of its author, Bhaskar Sunkara.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Sumit Kishore replied on Wed, 2010/12/22 - 1:27pm

Was hoping for a bit more insight into tackling performance issues and/or designing to prevent them, gleaned from and explained through real-life experiences. This article is very surfacal.

Josh Marotti replied on Wed, 2010/12/22 - 1:48pm

Claiming ORM overhead causes issue is sure to get people fired up.

Personally, I'm not a fan of ORMs, but it is a personal choice (I find that unless you have everything setup perfectly, it is more work to get it working the way you want than just writing the damn queries/rowmappers by hand). Having said that, I know most ORMs, when properly coded and configured, see minimal, rarely noticeable, overhead.

Patrick Moran replied on Wed, 2010/12/22 - 7:46pm

Thanks for posting the article.  I agree, its a pretty basic post, but these are key problems we see over and over. For readers looking to actively monitor and manage performance problems in their apps, I reccomend http://www.newrelic.com - we are a saas app that makes it easy to get visibility into app problems and challenges.  Sets up in 2 minutes.

 

 

Carlos Hoces replied on Thu, 2010/12/23 - 4:42am

You have made a good and detailed presentation of troubles, common to almost all programming languages.

Talking about Java specific issues, I'd like to share some thoughts:

1.- Memory leaks. The most common sources for leaking memory seem to come from two bad practices: forgetting to remove listeners no longer needed, and forgetting to close opened resources. This last one could be a source of dramatic leaks, in cases where JDBC is used, and we forget to close result sets from queries, or statements.

2.- SQL. If performance is a must have, we need to directly use JDBC methods. It's not so complicated. In cases where the SQL engine is not known at design time, we only have two options: use an SQL layer engine like Hibernate, or develop low level JDBC SQL access for any potential target SQL dialect out there. Either choice has its benefits and drawbacks; but since we are talking about performance, the obvious choice is JDBC low level development.

3.- Threading. The only true parallel execution occurs when every task gets processed by its own hardware processor, and there is no data sharing among different tasks. Any other condition breaks parallelism up to some extent. The main reason to use multithreading, when systems and execution conditions don't allow for true parallelism, is to provide a good user interaction with the application. We don't want user to wait for tasks completion, when the expected results may block other user selections. At last, all tasks have to complete somehow, at some time. The need for synchronization is not related to performance, but to data process requirements. Nevertherless to say wrong thread development, with or without synchronization, leads to performance issues, at least.

Dapeng Liu replied on Thu, 2010/12/23 - 10:14am

for performance of ORM, it is really down to your mapping some ppl tend to map a full object graph (lots of linked @OneToMany @ManyToMany) but this tends to be tricky when you want to tune the performance personally, i still prefer the 'de-normalized' mapping, meaning, join the selected result in memory rather than ORM level or DB which gives huge flexibility when apply customized caching and fine tuning the queries, however at a cost of making the query a bit complex

Ashutosh Shinde replied on Tue, 2011/01/04 - 1:30am

"Issues arising from synchronization are often hard to recognize" - what tools would you recommend the readers based on your experience? I normally use Thread Dump Analyzer for finding out deadlocks. 

Ashutosh

www.avekshaa.com

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.