Flex 4 and FlashBuilder 4 Released

Start your engines...

You can get the scoop here:

http://blogs.adobe.com/flex/

Spring and BlazeDS Best Practices

I recently wrote a white paper for a client to assist them in ramping up with Spring and BlazeDS Integration (SBI) best practices. The link below will allow you to download the white paper.

It contains many links to helpful downloads and assists in a "painless" install and configuration for this solution set. There is also a java and flex example app to get you started. Enjoy...

BlazeDS Best Practices

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.

Flash 9 and 10 Compatibility Matrix

I was recently tasked on my current project to generate this. I hope it helps some of you in communication regarding Flash support across multiple OS and Browsers.

Matrix

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.

DB Design id/name Debate

I have wanted to blog about a simple DB Design approach that can make or break facilitation of coding, readability, maintenance, and ultimately warehousing approaches.

It is the "id"/"name" debate. For instance you have a "Status" table. In this table you have a list of status names and their respective surrogate keys in the id field driven by a sequence or identity field (Oracle/Sql Server).

Best practice in this situation is to label your id field status_id or statusID (Oracle/SQL Server). Due to upper casing in oracle an underscore is used for readability and has developed into a standard for Oracle DB naming, SQL Server allows mixed case which parlays nicely into your object model where the C-based syntax world has standardized on camel case for class properties and doesn't require aliasing in SQL code.

This very issue while on a project with a Microsoft Centric Dev working for the first time with an Oracle DB was a huge bone of contention. He had to alias all his sql due to the underscores as this made it easier for us when copy/pasting sql return assignments. Made good sense and I felt for him being a Oracle newb. This is one thing SQL Server has over Oracle when it comes to readability.

But back to the topic... The reason behind prefixing the id field with table name is for readability when joining. Imagine if all tables had id/name fields. This would be confusing rather quickly now you'd have to prefix at the very least in the table where the foreign key was assigned and I've seen worse. A child (foreign key) table that has a label that doesn't necessarily relate to the parent. For instance stat or statpkey... Acckkk! If the parent only had statusID and in turn the child table also had statusID, the developer, sys arch., dba will readily understand the relationship.

When it comes to the name field it is my opinion that this field should be prefixed too, because you run into name being everywhere and pending on whether you had a good SQL coder or not you are going to have to alias that field every time you use it which is a pain when many IDEs out there generate sql code for you.

Lastly when it comes to the name field you have to think about whether or not data mining will be used in the future against this data. Hopefully in a data warehouse. When it comes time to building the warehouse from the transaction db solution, generating the SQL and DDL to do so is much more straightforward and will facilitate flattening of the tables as the table in the originating transaction db will be prevalent in both the id and name fields. I look forward to your comments.

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.

Thank You Greater Miami Chamber of Commerce

I spoke to the GMCC yesterday afternoon about SEO and how Universal Mind has overcome the challenges of spidering flash based solutions.

It was an enjoyable presentation and I appreciated the genuine interest and questions from the attendees. Thank you Chamber! I look forward to visiting again. The "download" link below will allow you to save the PowerPoint presentation.

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#" />

More Entries


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