Flash Camp Atlanta

If you are looking for a great day of Flex and Adobe discussion/training sign up for Flash Camp Atlanta!

It's on Aug. 28th and starts at 8 for the special introduction course with general sessions starting at 9. You can't beat the training you will receive from these experts in Flash and RIA; plus it only costs 50 bucks!

I am planning to attend, hope to see you there; click on the image to register:

jvm.config Tuning Tip For All Server Side Java Solutions

I have been wanting to blog about an experience I had not too long ago on a project where the jvm was consistently throwing OOM errors. It had me banging my head against my desk for a few days attempting to trace where the culprit was.

Was it code related?... yes, was it bad code?... sort of, was it very very very intense code (looping over many sql calls and instantiating many objects)?... YES! The challenge here was to apply a quick band aid rather than redesign this rules engine that had the characteristics listed due to time constraints. It is important to note I was not responsible for the poorly written code 8-).

I had to first identify if there were memory leaks due to this code. To do this I utilized YourKit Java Profiler. They have .NET and Java profilers that allow you to monitor their respective runtimes. YourKit Profiler is very simple to configure within the jvm.config file (I'm not going to get into that in this blog). My point here is that I witnessed memory steadily climb and at times spike, but was only able to reclaim memory when executing a manual GC. UGGG!!! So, no memory leak, but the runtime was hanging on to what it had... Why was the GC not reclaiming memory quickly on it's own? I had all the BP jvm args of old, etc., etc. ParNewGC and RMI to no avail.

And to get back to the initial issue; the blasted OOM error. I searched high and low and identified a thread on a Sun forum that there were issues with jre 1.5 that ultimately threw a OOM error if the runtime was unable to reclaim memory during a GC within a given time frame. The workaround for this was to set a time constraint in the JVM (which didn't work) or install 1.6_10 or later. This was my first step. I installed this JRE version and pointed my jvm.config to it. The application ran fine under this JRE except that I was still seeing the memory creep to the ceiling with no reclaim.

I then read on one of Sun's GC tuning white papers the following paragraph:

The -XX:+AggressiveHeap option inspects the machine resources (size of memory and number of processors) and attempts to set various parameters to be optimal for long-running, memory allocation-intensive jobs. It was originally intended for machines with large amounts of memory and a large number of CPUs, but in the J2SE platform, version 1.4.1 and later it has shown itself to be useful even on four processor machines. With this option the throughput collector (-XX:+UseParallelGC) is used along with adaptive sizing (-XX:+UseAdaptiveSizePolicy). The physical memory on the machines must be at least 256MB before AggressiveHeap can be used. The size of the initial heap is calculated based on the size of the physical memory and attempts to make maximal use of the physical memory for the heap (i.e., the algorithms attempt to use heaps nearly as large as the total physical memory).

Note: -XX:+UseAdaptiveSizePolicy is on by default so I don't explicitly define it in my args.

Amazingly, once I added this to the args, removed ParNewGC (enabled UseParallelGC) the server ran flawlessly for days and days without a restart. I was serving requests into the millions without a restart!!! A partial arg list specific to these setting are below, please let me know your thoughts and concerns as I always enjoy constructive feedback.

java.args=-server -Xmx1024m -Xms1024m -XX:+AggressiveHeap -XX:+UseParallelGC -Dsun.io.useCanonCaches=false -XX:MaxPermSize=512m

Note: This was for a ColdFusion 8 instance.

Writing for ColdFusion 9

I just got word that I will be contributing to the books supporting the ColdFusion 9 release.

Adobe is making significant improvements as they continue to evolve the product.

I am stoked to be involved for a third release and look forward to working with a stellar team of authors.

Flex Camp Miami

I wanted to blog a reminder that I am promoting Flex Camp Miami (http://www.flexcampmiami.com). It will be on the University of Miami campus. A great place to meet during the winter season and registration is only $30!!!!

The testimonials alone are reason to attend: http://www.flexcampmiami.com/page.cfm/testimonials.

It's an opportunity to learn from the industry's finest, network, discuss the daily grind, etc. I look forward to seeing you there!

Here is the Agenda:

Time Session and Speaker
8:00-8:30 am Registration
8:30-9:30 am Welcome and Keynote (Flex 4 Preview)
Brian Rinaldi, Universal Mind
Greg Wilson, Adobe

9:30-10:20 am Working With Data in AIR
David Tucker, Universal Mind
10:20-10:40 am Break
10:40-11:30 amIn Search of AOP for AS3
Maxim Porges, Highwinds
11:30-12:20 pm Merapi or How to Blow Your Mind with AIR
Andrew Powell, Universal Mind
12:20-1:00 pm Lunch (provided)
1:00-1:50 pm User Experience Design Topic TBA
TBA
1:50-2:40 pm Continuous Integration and Flex
Brian LeGros, Highwinds
2:40-3:00 pmBreak
3:00-3:50 pm ScrapBlog.com Speaker
3:50-4:40 pm
Mate Framework
Laura Arguello, ASFusion
4:40-5:00 pm Closing and Door Prizes

So as you can see, something for everyone. Look forward to seeing you there.

ColdFusion createObject "Component" and Pathing Performance

I haven't blogged in awhile due to schedule, but had to blog this experience I recently had while attempting to stabilize an application and enhance performance.

I have always taken for granted that createObject was lightning fast... Well, as fast as feasibly possibly under a given JVM.

I think I was dead wrong and this may be an issue for Adobe to address. I am unclear on the internals of course. But I have been up against OOMs on my current project and wanted to test out using soft reference (cached objects) and use duplicate from the cache rather than createObject.

Far stretch I know... but hey it was worth a try. What was revealed was that performance was negligible and createObject was faster in some intervals. Memory behaved the same, no real bonus. So in discussion with a fellow consultant I told him I'd ship a zip to him for test purposes as he had said he'd seen a significant performance enhancement with duplicate (not true by the way).

What happened next totally shocked me. To simplify the test code I snagged my VO.cfc out of it's proper place (several dirs down i.e. sitedir, com, bus, app, model, vo.. you get the idea) and put it in the root of the calling cfm. I then removed all the pathing (dot notation) from my createObject call and executed the cfm to see if it would run ok after the change.

The test was a loop of 10k over this create object call. I was seeing execution times of around 30 seconds. When I ran the updated code it went to 577 milliseconds... I am still befuddled by this. Is there that much overhead with pathing?

I initially thought it was a mapping issue because I had been using mappings, but absolute path from root was just as slow.

Please Adobe tell me this is Sun's jvm and not your code. I know this is negligible with 100 or so creates, but imagine the boost if I did find something here.

For clarification I am running on a Mac (OS X, CF running in JBOSS), but also tested on my old Dell (XP, CF running in JRUN). I didn't see as dramatic a difference on WIntel, but my exec time went from 30 seconds to 4 seconds. I am happy with 10x faster on Windows too...

Any insight here is greatly appreciated. Example Code:

<cfscript>
      currentTime = now();
    rqaArray = arrayNew(1);
    initTime = getTickCount();
         for (index=1; index lte 10000; index = index + 1)
{
    // pathing example replace vo reference with     //this pathing call com.mercer.mercerOnline.model.RQASummaryVO
    rqa = createObject("component","RQASummaryVO");
    rqa.rqaID = index;
            rqa.type = "theType";
            rqa.createDate = currentTime;
            rqa.submitDate = currentTime;
            rqa.client = "currentClient";
            rqa.clientID = "clientID";
            rqa.status = 6;
            rqa.userID = 123456;
            rqa.agencyID = "agencyID";
            rqa.predecessorID = 0;
            rqa.locked = false;
            rqa.deleted = false;
            rqa.title = "The Title "&#index#;
            rqa.policyNumber = "thePolicyNum";
            rqa.agencyName = "agencyName";
            rqa.totalPremium = "totalPremium";
            rqa.hasMessages = false;
            rqa.isAssigned = false;
            rqa.assignedTo = "";
            rqa.proposedEffDate = currentTime;
    rqa.proposedExpDate = currentTime;
    rqa.agentName                     = "agentName";
            ArrayAppend(rqaArray,rqa);
         }

         endTime = getTickCount();

         totalTime = endTime - initTime;
</cfscript>
<cfdump var="#arrayLen(rqaArray)#">
<cfdump var="#rqaArray[10000]#" />
<cfdump var="#totalTime#" />

A Mashup That Makes Sense

Recently Andy Powell won a WII for his submission into the 360 Flex | API Contest.

His winning application is a great example of leveraging multiple APIs that at first glance, one may be challenged in connecting the dots with regard to how they could be integrated into a single intuitive application. When I first looked at Andy's initial layout and functionality as intuitive as it was, I got stoked because I could see that this application could be enhanced visually and functionally; so I am blogging about the enhancements I made to that effect.

First, I had some .css in mind to give it that Ribbit Green theme. I adjusted the layout of the various nested canvases and converted them to use a form which allows for formitem conciseness with regard to alignment etc and allots for a default button (integrated form 'enter key' functionality).

I sized down the respective API images into the main panels control bar (will be applying links shortly) and enhanced the map functionality which allows for a unique icon (hotel) to identify the selected hotel from other hotel POIs on the map. Each time a search is performed the past icon is returned to its initial state and the newly selected hotel gets the new icon (member variables used to allow for this). I will be styling the MapQuest info windows that pop up with selection of a POI shortly as the very customizable MapQuest API is 100% extensible.

I then relocated the RIBBIT dial up interface and adjusted dialing status to persist in the connection labeling area rather than separately at the bottom of the form to save real estate. Lastly, I wrapped it in a panel with the hotel details form and nested it within a panel along with the MapQuest tilemap component. This panel will soon be a slide in that will open/close via grid selection and panel close feature. Please check out the new app on Andy's site here; Ribbit, Kayak, MapQuest Mashup and book your hotel today 8-).

FYI, souce code is located at Andy's Google code site here: AP's GCode site

Why VOs (transfer objects) are good...but they can be abused like...

any other design pattern....

Sorry for the confusing title, but long titles are rather lame. So you're a flex cf, java, or php developer and you are leveraging all the beautiful one to one mapping associated with server and client object creation.

"YES!", you said. No more guess work; my server vals returned can be readily passed around within my AS code with the ease of code insight! Ctrl-space... wow theres my property! Ok, getting tacky I know.

So we embark on our design of a sytem always using VOs no matter the cost. Eee gaadd stop now. VOs, pending on design approaches may possibly have multiple layers of nested VOs YIKES!

Everyone knows that Rambo's weapons of choice were the bone cutting hunting knife and explosive bow and arrows. But there were times when he had to pull in the heavy artillery or perform a sneak attack with a much more lightweight approach like a choke hold (ahh, the violence of my youth...).

This is why VOs can be a problem if implemented without understanding the performance ramifications that can be incurred if they are always used.

Here's a real world scenario. Requesting an array of 100+ VOs from your middle tier that each have nested arrays of child VOs. Imagine just having two child VOs and the impact that could have on performance with this approach.

You call in to pull back the parent VOs that contain an array of child VOs (say 5) that all need to get created for each item in the array. So in this process we are creating 100 parent objects and internal to each we are creating 10 child VOs. This yields 1000 objects which each need to get created and the memory and process grow each time you do so on your middle tier (now add just a few users doing this incrementally over the first couple of hours).

I'm being facetious here of course as this isn't a very high number. But why return such a dense object to the client unless you were going to use it. There is a lot of wasted horsepower with this approach. Think of the scene with Rambo emptying that M60 E4 machine gun and never hitting his target... Rambo

A better approach is to pass back a snapshot of the data directly from your middle tier and pull back its VO representation when an edit needs to be performed or the VO truly is required to facilitate a process in the application.

So if you are going to populate a grid, I don't recommend doing it with VOs and if you absolutely have to create an array of VOs understand the possible performance impact (and data stagnation) that can ensue if the VO is of a complex nature and how it can impact the health of your server and ultimately the user experience.

The J2EE Core Pattern docs on Transfer Object speak to this. Check out the "Consequences" section of caching large sets of VOs. Line from the article: There is a trade-off associated with this strategy. Its power and flexibility must be weighed against the performance overhead... THE LINK

Flex ColdFusion Extension Wizard Gotcha

This entry will hopefully be brief and to the point in regard to the title. I want to start off by stating how much I like the ColdFusion extension support in Flex 2 and hope to see Adobe add extenstions that support other languages/middle tier solutions as well hint: (java, php, c#).

There is nothing like beginning your application architecture and development with an out of the box mvc approach utilizing well known approaches to server side development utilizing delegates, services, daos, gateways, and value objects.

Where I see a major problem with the extension is how it is implemented. I have been involved with several projects that have utilized Flex and ColdFusion and upon initially beginning my trek into Flex 2 I saw this issue right away only because I have been working with ColdFusion for 10 years, have consulted on its benefits, scaled servers, architected highly successful and efficient enterprise solutions with it, and know the do's and don'ts...

The problem I am speaking of with the CF extension implementation is the iterating over read functions in the data access object cfcs.

To be more clear, in the templated or skeleton dao cfcs there are db calls made, mostly crud calls. The read function I am discussing here is "r" in crud. The problem is that in many cases I've seen engineers design a composite or aggregate VO. This is a VO cfc that contains other VO cfcs.

This is a perfectly efficient and best practice OOP approach that ColdFusion handles very well. The problem arises when a child resultset of ids (usually a query or array) is used to iterate over and call the read function in the dao to get the vo properties from the db to return via remoting to the Flex application.

The main issue here is performance, specifically with the possible 100s of calls that can be made to the database in one ColdFusion request from the application. Imagine a dump truck going 200 times to the gravel pit taking one pebble, with today's gas prices I don't think you'd last long on the job if you took that approach 8-)... This is what you are doing when you loop over queries. Not only could these calls prove to be slow and taxing on the database but it can also lock up threads in ColdFusion and create cpu and memory spiking out of the shoot. You also have to deal with any kind of network latency that may exist between your CF server and the database as well. AAAACKKKKK!

But there is a solution: First a band-aid needs to be applied. For these complex objects an investigation must be made to locate where these iterating processes could be going on. Second, there is a function in ColdFusion that automagically converts a query field to a comma-delimited value list(or delimiter of your choosing). The function is called "valueList(query.column, ',')" there is also a quotedValueList for strings. With this list you could then use the SQL IN clause on the hopefully indexed id field used to pull back the child VO data. Add another function in the dao or better yet the data gateway that specifies readMultiple or getMulipleObjectName...

Once this is done the code should truly be refactored to call the database only once for all its data (think one cf call/one db call). If you did not know ColdFusion is one of the most robust languages when integrating with the more popular dbms on the market (Oracle, SQL Server, MySQL, DB2, Informix). The cfstoredproc tag allows you to call into a stored procedure to get procedure resultsets.

cfstoredproc also allows a developer to return multiple resultsets from a stored procedure to ColdFusion. So, one call to a stored procedure in Oracle that returns 2,3,4,or more ref cursors to ColdFusion. These could be all your objects' data which only requires you to loop once over all of them (maybe some nesting and brief logic to create them, but still 1000s of times faster than separate db calls for each loop).

This may be one of the drier entries I've had (no code, pictures, jokes). But I hope it helps you when using and not abusing the ColdFusion extension wizards in Flex 8-).

ColdFusion 8 Getting Started

Ben has posted all the code and a few of the electronic chapters. Enjoy!!!! THE LINK

Ba BYe CFDJ...

Was anyone really reading it anymore anyway? ColdFusion is such a mature technology with a huge blogging community behind it. What did CFDJ have to offer when you can head over to forta.com, coldfusionjedi.com, or yours truly to get answers?

I have answered many questions for those who have worked with ColdFusion and having written for the journal in the past a part of me feels sad for that, but this move by SYS-CON in no way should reflect on the technology itself. With ColdFusion 8 out it is going to significantly make an impact in areas of enterprise report solutions, image storage and manipulation, AJAX integration, and the list goes on...

More Entries


Copyright Strikefish, Inc., 2005. All rights reserved.