Nov 30 2008

Good Practices For Scaling ColdFusion Applications

Posted by Mike Brunt at 10:00 PM
6 comments
- Categories: ColdFusion | JRun-J2EE

These last few days I have been thinking that of all the places in the incredible line-up of Adobe products that my place, in The Heart Of The Matter, the JVM, must appear to be so mind numbingly boring. I mean, good grief, ColdFusion, Photoshop, Dreamweaver, Fireworks, Flash, Flex, AIR, PDF's, Centaur etc etc. Well, I actually find where I work to be very exciting and very rewarding; I know I should get a life!.  Hang on though, we are gravitating from 32-bit to 64-bit architecture which is very significant and critical because, since the advent of web applications, application memory management has been a constant challenge.

Even more basic than that, much of what we all do will end up being served to clients via something.  It could be via printed media, it could be via audio or video; nevertheless, somewhere in that mix there will probably be a server component. In the case of printed media the server may not be so obvious to the reader.  Spare a thought then for that server which will somewhere at sometime be impacted by the creativity we are producing. The web world is unique in the annals of computing, in my opinion.  The rapid processing of requests and responses (threads) is the most important and basic need in web applications.  The greatest cause of problems is threads which are not released quickly and memory leaks; the former can sometimes cause the latter but not always.  Not always because the way that current JVM's work, in terms of memory management, is via a process called garbage-collection. The memory space of the Sun JVM is divided into three basic areas; new generation aka young, old generation aka tenured and permanent generation.  At a basic level, the young generation is where all new objects o when first created, the old is where they go after being around for a while and not collected by the garbage collector and the permanent generation is where the class files for JRun-ColdFusion live. What I typically observe, via verbose garbage collection logging, is that the default settings for all JVM's is inadequate to support ColdFusion and Java (jsp) web applications.  The default maximum heap size, young and permanent heap sizes are almost always not big enough. If you are still interested, please read on.

At the simplest level, objects which reside in memory are inspected by the garbage collector every "x" time-slice (decided by the default behavior of the collector).  They are inspected to see if the application still needs them; if there is still a "reference-pointer" to them from the application.  If there is, they are not collected and are left in the young generation.  One other thing I have observed is that collection from the young generation is more efficient than collection from the old generation.  After around 40-45 attempts to collect the object from the young generation it is moved into the old generation. The ongoing garbage collections are brief and take milliseconds; however, Full Garbage collections can take seconds and that is significant because a Full GC is typically a "stop-the-world" event.  This means nothing else happens on the server whilst a Full GC is underway.  We only want a Full GC to occur as and when necessary and we want that to be as infrequently as possible and to be as short as possible, in duration.  How we code will have an impact on this garbage collectioncycle.  The math is simplistic, the more objects the more memory is needed, the longer they hang around, the more memory is needed.  

Threads play their part because we have a finite number of threads. In a default ColdFusion 8 installation we have a maximum active thread ceiling of 25; this should be more than adequate.  However, if we write our code so that a process can take a long time, we can hang up threads.  When we run out of threads application performance will slow-down and the answer is almost never to dedicate more active threads, the answer is to find out why threads are hanging around.

All objects created reside in memory for some period of time, in ColdFusion, three scopes are worthy of particular note; Request, Session and Server.  The Request scope persists objects for the length of a single request and is typically benign and efficient.  The Session scope pertains to a single users session and dies either when a users session ends (via a log off the session) or when the session times-out as set either in the ColdFusion administrator or in the application code.  The Application scope pertains to a single users session and dies either when a users session ends (via a log off the session) or when the application times-out as set either in the ColdFusion administrator or in the application code.  The Server scope lasts from when the scope-variables are created to when the server is next stopped and started.  Another important point relating to these scopes; the Request scope is available only to that single request and objects residing there should be available to be garbage collected after the request completes.  The Session scope relates to everything that a single user does, the Application scope is available to all users in an application, in my experience, objects in these scopes do not die until the timeout as set in either the ColdFusion administrator or the application code, is reached.  The Server scope is there and available to all applications and all users until there is a ColdFusion or physical server restart.  The Application, Session and Server scopes will all have references to them from the application, the garbage collector will not collect them the first time around and they are most likely to be the cause of memory leaks if there are memory leaks.

To bring this all together, here are my broad brush recommendations for creating efficient ColdFusion applications, as we code, this is based on 9 years of troubleshooting ColdFusion and JRun applications.

Take great care when using Application, Session and Server scope variables.  Create them in as few places as possible and at as high a level as possible in the application.  Use the Client and Request scopes, where possible. If you are using a memory resident "framework" ModelGlue-mach-ii-FuseBox-ColdBox-ColdSpring-Reactor-Transfer or a home grown framework residing in the Application scope, take care to make sure they are efficiently used and bear in mind that you will need more JVM heap memory as that is where they will live. If you are using a community supported construct such as ModelGlue, ColdSpring etc, it is not a good idea to make changes to the core.  Take care with locking the Application, Session and Server scopes, my recommendation is lock only variables creates-writes and used a named lock instead of scoped locks.  Do not lock reads, that is not necessary and can slow down application performance. Avoid copying scopes to another scope, for instance, I have often seen Application and Session scope variables "copied" to the Request scope.  My opinion is thatthis is not good practice and is not necessary.  This was typically done to avoid the need to lock shared scope variables and in CFMX 6.1, CFMX 7.x and CF8, the locking of shared scope variable reads is no longer necessary.

Look carefully at all code that calls out to a dependency such as a Database, LDAP server, Media server, shared file storage etc.  Avoid code constructs such as loops in these cases.  We need all threads to process as quickly and efficiently as possible, as noted above.  Fix all bugs before moving code to production.  If you need a formal error collection mechanism, perhaps something is amiss; yes I know this is a somewhat controversial point of view.

Without fail and I mean that literally, without fail; load test all code before it gets to production and fix any problems revealed by the load testing, this s the most critical part of all.

Comments

David McGuigan

David McGuigan wrote on 04/28/11 10:55 AM

Any ideas on where to start to load test a CF 9 Standard / MySQL / Apache web app? I've been having an issue where a handful of times per day all sites ( though some *seem* to respond a bit faster than others during the freeze ) freeze up for a few minutes and then reconvene with original performance. During this time MySQL seems to still be responsive from a db IDE, but web pages are not.

Our server has gallons of RAM and CF has 10GB for both the min and max JVM heap size.
Thanks.
optimizare web site

optimizare web site wrote on 05/18/11 7:52 AM

The Cold Fusion technology can be used for the website optimization too. A fast website will be better viewed by search engines. I've performed some tests with that and it works well.
superdry uk

superdry uk wrote on 11/18/11 6:14 PM

Every superdry sale fans convinced superdry will be next huge designer. The colors of superdry uk are just amazing because they are universally flattering! It is a great alternative for people who are tired of buying out the entire superdry outlet line and are finished shopping at Our Superdry uk sale store.
resume services

resume services wrote on 12/13/11 10:37 AM

I'm developing a new online resume/applicant software package for my company with Coldfusion. I'm running into a problem because I can't seem to lock the core framework so changes can't be made. I tried locking the scope locks as was suggested, but then I can't seem to add variables. I know this is an easy fix, any suggestions would be great. Thanks
top ccna salary rates

top ccna salary rates wrote on 12/22/11 2:20 PM

Networking is the best option for utilizing coldfusion related items.

Write your comment



(it will not be displayed)



Leave this field empty: