Packing 100 megabytes of garbage into a 50 megabyte bag.
Tutorial Details:
With the increase in the popularity of blogs as a public diary, blogging hosts have been growing by leaps and bounds. So to the folks at Blog-City, it was clear that their site needed to evolve and grow. To address its growing needs, the company had just recently rolled out Blog-City version 2.0. As if often the case when a new application is rolled out into production, its performance does not quite meet expectations due to a number of factors, not the least of which was the sudden and seemingly random appearance of long periods of time when the application appeared to be hung.
At its core, Blog-City relies on the Blue Dragon Servlet engine (a CFML engine) and a database. Amazingly, all of this software was hosted on a fairly old P3 running Red Hat Linux. The machine, sporting a single hard disk and 512 MB of RAM, though powerful enough for past loads, was struggling to keep up with the growing load. Blog-City had become a victim of it\'s own success. Even so, this was all the hardware that was going to be available for some time.
Defining the problem
The first step in the process was to determine the cause of the sudden application slowdowns. First on our list of suspects was garbage collection. As we demonstrated in last month\'s column, the easiest way to determine if garbage collection and memory utilization issues are having a negative effect on your applications performance is to set the -verbose:gc JVM option and examine the log output. So we restarted the application with verbose garbage collection logging turned in, and patiently waited for the application\'s performance to fall off. Our patience paid off in the form of a very revealing gc log file.
From the initial analysis of the log files, it was apparent that garbage collection was the bottleneck in this application. This was evidenced by the frequency, duration, and overall efficiency of GC. A common reason for a higher than normal GC frequency is that the heap is barely large enough to accommodate all of the live objects that are currently in use and not quite large enough to accommodate the new ones that are being created. Though there are many reasons why an application may be consuming the amount of heap that it does, not having enough memory causes the garbage collector to thrash as it tries to satisfy the current need. In other words, the application will attempt to allocate a new object and fail, and upon failing, will trigger a garbage collection. If that GC fails to recover enough memory, it will force another, more expensive GC to occur. Even if GC does recover enough space to satisfy the immediate request, you can be sure that it won\'t be very long before the application experiences yet another allocation failure, triggering yet another GC. As a result, instead of the JVM servicing your application, it will focus it attention on the fruitless task of repeatedly scavenging for free heap space.
Though there may be many reasons why an application is consuming all of the available heap space, the expedient solution is to configure a larger heap, if more memory is available. Assuming that the application does not have a memory leak (or what we like to call unintentionally retained objects), it will find a \"natural\" level of heap consumption, which the GC will be able to comfortably maintain (unless the rate of object creation is so high that GC is always in a race to keep up). In this case, and the case of unintentionally retained objects, we will need to make changes to the application in order to obtain any improvement.
Read
Tutorial at: Click here to view the tutorial
Rate Tutorial: Tuning garbage collection in the HotSpot JVM
View Tutorial: Tuning garbage collection in the HotSpot JVM
Related
Tutorials:
|