How much memory does my ColdFusion variable really use? – Part III

Finally, nearly the last part (there’s one more coming…). In part II I talked about the different problems we’d run into using the instrumentation code out-of-the-box without modifying it for the special scenario of using it to size ColdFusion variables. We declared those issues solved (sic!) :-) – so let’s have a look at some code and how to use it. All I’ve done was to grab the example from Heinz’s JavaSpecialists newsletter and changed some of the signatures (from private to protected). I then wrote a class CFMemoryCounterAgent that simply extends MemoryCounterAgent and overrides some of the methods with modified versions to cater for ColdFusion (well, technically it’s probably overloading because I modified the signature…).

Also while I was at it – I added a second argument to sizeOf() and deepSizeOf() named ignoreFlyweights. That refers back to the last section of part II – it enables you to define if the (what we have defined as well-known) flyweights are going to be counted for the total memory usage or not.

This is the modified internalSizeOf() method, that’s being used to “filter” for the the two well-known “troublemakers” in CF as discussed in part II. When I was doing some further testing, I came across a few more scenarios that could cause the memory sizing to drift off, those have been added as well:

 private static long internalSizeOf(Object obj, Stack stack, Map visited, 
   boolean ignoreFlyweights) 
  {
    if (skipObject(obj, visited, ignoreFlyweights)) 
    {	
      return 0;
    }
 
    Class clazz = obj.getClass();  
 
    if (clazz.isArray()) 
    {
      addArrayElementsToStack(clazz, obj, stack);
    } 
    else 
    {
      // add all non-primitive fields, non-CF memory tracker objects and non-SessionContext objects to the stack
      while (clazz != null) 
      {
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) 
        {
          if (!Modifier.isStatic(field.getModifiers()) && !field.getType().isPrimitive() && 
            field.getType().getName() != "coldfusion.runtime.NeoPageContext" && 
            field.getType().getName() != "coldfusion.runtime.CfJspPage" && 
            field.getType().getName() != "coldfusion.monitor.memory.MemoryTrackable" && 
            field.getType().getName() != "coldfusion.monitor.sql.QueryStat" && 
            field.getType().getName() != "coldfusion.monitor.memory.MemoryTrackerProxy" && 
            field.getType().getName() != "javax.servlet.ServletContext") 
          {
            field.setAccessible(true);
            try 
          	{
              stack.add(field.get(obj));        
            } 
            catch (IllegalAccessException ex) 
            {
              throw new RuntimeException(ex);
            }
          }
        }
        clazz = clazz.getSuperclass();
      }
    }
    visited.put(obj, null);
 
    return sizeOf(obj, ignoreFlyweights);
  }

I’ve provided a .zip file (version 0.1.1) containing the source. If you don’t want to compile it yourself, just grab the CFMemoryCounterAgent.jar and apply it to your CF instance as described in part I. The .zip also contains a memorytest.cfm that should be self-explanatory and will give you an idea how it’s supposed to be used. If you want to compile it, the build file for Ant should do the trick – please note that there is a copy task in there that copies the file into the location of my CF installation’s lib folder. You pretty much would want to change that to copy the .jar file to a different location OR remove that copy task in the first place. Also – I’ve build and tested this on CF 8.0.1 on OS X. You need Java 5 or newer to run this in the first place and YMMV with other CF versions. If you try it and get weird results, let me know.

Edit: The .jar file is compiled with Java 6 and the Ant file targets Java 6 as well. Make sure that you potentially recompile the source and change the Ant file if you try to run this on Java 5.

Please keep in mind that all results you’re getting from this are JVM-based estimations and sort-of right. Also, I would strongly discourage you to build totally messed-up code for the sake of saving 250 bytes or similar. Don’t forget that the JVM has a reasonably well-working garbage collection and the GC will collect most variables that you create on a page very quickly in the first place. The techniques shown here are more for information and to raise the behind-the-scenes awareness. Besides that, it’s just interesting to see how CF deals with the different variable types. The next (and final) post of this series will have a look at some results and try to explain those. Stay tuned.

Post to Twitter Post to Delicious Post to Facebook Post to StumbleUpon

How much memory does my ColdFusion variable really use? – Part II

Here we go – part II of an approach into sizing ColdFusion variables from within ColdFusion. In part I I introduced the problem we’re trying to solve, a general solution (JVM instrumentation) and also pointed you to the JavaSpecialists newsletter #142 for a working solution (from a Java point of view). Heinz also commented in part I and pointed out that there is a full-blown open source project named java.sizeOf() that provides a complete solution from a Java point of view.

How does it work?

This post is geared towards the problems the out-of-the-box Java solution runs into. Let’s first have a look into two different ways of calculating the memory usage of a CF variable with the approach described so far.: sizeOf() vs. deepSizeOf() respectively shallow vs. deep. If you’ve done any work structs in ColdFusion this concept should be somewhat familiar (there are shallow copies/references as well as deep copies). In our use of the terminology shallow will refer to measuring the memory usage of the object itself and deep will refer to measuring the memory usage of the object as well as its fields (members) as well as the parent class(es) and their fields up the object hierarchy.

How does the code do this? Basically it’s using a stack and a hash map to keep track of what do to and what already has been measured. First step is to grab the CF variable (which is a Java object), check a few things (more below) and then throw all members of the object onto the stack for further processing. After that, the superclass gets processed the same way, more stuff gets thrown onto the stack and popped off the stack again when we’re running out of things to process and measure.

Ignoring types

This fact alone contains a few interesting surprises. When I started measuring slightly more complex CF variables than simple Strings or Numbers, I got crazy figures of several MB for a simple struct. That obviously couldn’t be right. Using Java reflection on a few CF variables, such as structs or arrays, I easily found the “culprit”: reference(s) to coldfusion.monitor.memory.MemoryTrackerProxy. Sounds like the CF 8+ server monitor subsystem to me, but I might be wrong. But anyway – following this reference along up the object hierarchy creates the outrages figures for a struct and other variables. The Java class behind a CF struct is coldfusion.runtime.Struct and it actually contains a getter and a setter (getMemoryTrackerProxy() etc) to work with the MemoryTrackerProxy. For our purpose of measuring the memory used for the struct and its content, we certainly don’t need to follow the links to MemoryTrackerProxy when the instrumentation works itself through the object stack. What that basically means is that we have to ignore all members of type coldfusion.monitor.memory.MemoryTrackerProxy when we trace the object tree.

Just in case you’re interested, the inheritance structure for a CF structs from a Java point of view looks like this:

java.lang.Object
|-  coldfusion.util.CaseInsensitiveMap
|-  coldfusion.util.FastHashtable
|- coldfusion.runtime.Struct

After having “fixed” the MemoryTrackerProxy issue, common CF variables worked fine. I still ran into issues with some persistent scopes. Further testing showed that some of those contain members of type javax.servlet.ServletContext. Now – following those when tracing memory usage also creates huge amounts of memory being used because you’re pretty much including a lot of the overall Java API. That particular happens when dealing with measuring the application scope. Therefore javax.servlet.ServletContext is another class I’m filtering for and ignore when measuring memory usage.

Important: Both decisions are made sort of arbitrary. One can argue that following the references and including javax.servlet.ServletContext for the application scope for instance would create the “real” amount of memory used for the application scope. My answer to that would be: yes, that’s fair enough and it might be a valid point. I’ve made the decision not to include it because it’s not what I want to measure here.

Flyweights

Just a few quick word on flyweights or the Flyweight Pattern. I don’t want to dive into the specifics of this pattern, just follow the linked explanations if that’s of interest for you. But – I want to give you a plain language description of what it is (from 30,000 ft): Basically the Flyweight pattern is a way to manage memory very efficiently by sharing and pooling objects whenever possible. That’s pretty much you’d need to know for the purpose of this exercise. Ah – no, hang on. What again does this have to do with Instrumentation and tracking memory usage?

Well – think of a pool of Integer objects or internalized Strings. For us, it’s pretty much impossible to say if a particular object of such characteristics is used for solely our case or if it’s reused in a lot of other places in the app. Maybe we have our own instance of an Integer xyz and therefore the memory usage of it should be counted towards the use of our complex ColdFusion variable. But maybe we just borrowed an Integer abc for the fraction of a blink that was somewhere in the pool anyway and therefore just quickly using it didn’t do any “harm”. We don’t know and that’s why we check. For Integers we would basically do: obj == Integer.valueOf((Integer) obj). If that returns true, we know it’s a shared flyweight and shouldn’t contribute to the overall memory usage. For Strings it means to check the .intern() method (as described and linked above). There are a few more types for which such testing makes sense.

Still, one can argue that one’d want to see the memory usage ignoring any flyweight/JVM concerns, so I made that configurable with a switch. I personally think it’d be better not to include them, but both will possible.

That’s it for now – part III will comprise the actual Java code and .jar file to be used in ColdFusion and some examples. I should actually write another post giving a few more explanations on using Java reflection in ColdFusion and what it can be good for (basically tinkering with undocumented features :-) .

Post to Twitter Post to Delicious Post to Facebook Post to StumbleUpon

How much memory does my ColdFusion variable really use? – Part I

Recently I’ve been dealing quite a bit with ColdFusion from an infrastructure point of view – clustering, monitoring, system tuning etc. One particular thing I (and I know of at least some others) have found missing was an easy to use and realistic way of figuring out how much memory a particular ColdFusion variable really uses. There are a few approaches around that regularly pop up on mailing lists to roughly estimate such a figure from code. There are also a few tools such as SeeFusion, Fusion Reactor or the ColdFusion Server Monitor that provide assistance when it comes to figuring out JVM memory usages or even are able to break usage down to a scope such as the application scope.

All that’s good information, but it didn’t provide the information I wanted in this case. I literally wanted to be able to create an array or a structure in CF and see how much memory the instantiation of this variable will take. I don’t see a way to get this information from ColdFusion itself, but here’s a nice feature of the underlying Java platform to the rescue: JVM instrumentation (available from Java 5 onwards).

If you followed the link above you would have seen the getObjectSize(Object) method and its description “Returns an implementation-specific approximation of the amount of storage consumed by the specified object.”. Ah, cool. That sounds about what we want, right. Take an object – throw it into that method and get back the amount of storage used, doesn’t it?

Notice the following restrictions:

  • implementation-specific and
  • approximation

What does that mean for us? Well – basically what it comes down to is: You get an approximation, it  might not be correct to the last byte. The JVM will try hard, but it might just not be 100% exact. Also, speaking of the JVM – the number it returns will be correct for your hardware, operating system and JVM used. To give you an example – the figures I get on my 64-bit OS X 10.6.2 with JVM 1.6.0_17 might be different from someone on 32-bit Windows with a Java 5 JVM or even a JVM 1.6.0_16. So – to sum it up: YMMV.

I started playing with instrumentation a bit and then found issue 142 of Heinz Kabutz’s JavaSpecialists newsletter. In there, he provides a JVM-instrumentation based memory counter that seemed to do exactly what I wanted to do. The idea is that you have a MemoryCounterAgent class that provides two static methods: sizeOf() and deepSizeOf().

The way to use his code is rather straight forward. Compile the MemoryCounterAgent.java provided there – either with a tool of your choice or use the ANT scripts Heinz has provided. The result should be a .jar file that you’d best put into the lib folder of CF respectively Java. I’ve done all this on CF 8.0.1 / OS X 64-bit installed in a JRUN4-based J2EE installation. The folder I place the .jar file in this case is /Applications/JRun4/lib.

To hook your JVM into the instrumentation agent, you need to modify the JVM arguments. You find those usually in the jvm.config file in the bin-folder of your CF or JRun installation. The idea is to add a -javaagent argument in front of the other, existing arguments that points to the .jar file you’ve created and placed in lib before.

java.args=-javaagent:/Applications/JRun4/lib/MemoryCounterAgent.jar

Restart ColdFusion and after that you’ve got the instrumentation available for ColdFusion code. Put the Java object in your CF code (it’s static, so don’t instantiate it) and call a method of it:

<cfscript>
	oObjectSize = CreateObject("java","eu.javaspecialists.tjsn.memory.MemoryCounterAgent");
	myText = "This is a string";
	WriteOutput(oObjectSize.sizeOf(myText));
</cfscript>

“What’s the catch?”, you might ask. Well, there are a few. First of all – the unmodified code works for a variety of different CF variables, but it pretty much provides weird results for some others. The reason for this is that a CF variable is basically a Java variable. Strings in CF are of type java.lang.String – easy. Arrays in CF are of type coldfusion.runtime.Array and most complex CF types have such a non-trivial representation in the Java world. Those Java classes contain CF-specific implementation details and hooks into other parts of the ColdFusion infrastructure that really blow out and misshape the memory estimations the JVM instrumentation provides. There are ways around that (by using reflection on CF variables to find out how they are constructed, but that will be covered in part II of this series of blog posts).

The second issue are flyweights. For all those of you who have no idea of what that means – the flyweight pattern is a way to manage memory that is used for certain types in Java and its JVMs. Using (and including) flyweights in memory calculations can produce significantly different results from not using them. Also – that will be covered in more detail in part II or III.

Anyway – there are reasonable solutions for both issues, I believe. I’m currently building a CFMemoryCounterAgent class that provides memory tracking on CF variables as close as it gets – stay tuned, more on this here in the next few days.

Post to Twitter Post to Delicious Post to Facebook Post to StumbleUpon

Speaking at webDU 2010 (May 6 and 7 2010, Bondi Beach)

I’m again speaking at this year’s webDU (and it’s going to be the 8th time in a row – I think the only other people who have presented at each MXDU/webDU since it started in 2003 are Andrew Muller and Mr. Geoff Bowers himself now, yay!).

BTW: Did everyone realise that the registration for webDU 2010 is open and that the Early Bird price (AU$ 695 is really a bargain for the two days) runs out on March 7? Register now, but latest on March 7 please.

My topic will be: “It doesn’t always have to be relational – Introduction into CouchDB”. Although this session is going to cover a lot of content specific to CouchDB, you can bet that you’re going to get a whole lot of information on how to use Couch with ColdFusion and Flex.

Here’s the full session abstract:


Web developers have grown into the habit of pretty much solely relying on relational data base management systems to store the data of web applications. But besides the well-known RDBMS there is a huge community of supporters of alternative database systems out there: Object-oriented database management systems, hybrids between OO- and relational DBMS and many more. And then there’s CouchDB (subtitled: “relax”) – a document-oriented database that recently got promoted from the Apache incubator to becoming a full-blown Apache-supported open source project. CouchDB is fundamentally different from what you’re used to, but it offers a refreshing and different approach for storing data in your web application and it actually scales tremendously well in large web apps.

In this session, you’ll get an introduction into CouchDB, its API and the mechanisms behind the API and we’re going to look into hooking CouchDB into technologies like Flex and ColdFusion.

Post to Twitter Post to Delicious Post to Facebook Post to StumbleUpon

I’m flying an AirNZ 777-200

Well, in a simulator, but still… :-) The next action item after being to the Engineering base was the 777-sim ride. Air NZ has two simulator and training buildings in the vicinity of Auckland Airport. The one that hosts the 777-200 simulator also houses a Q300 simulator (if I remember correctly), used by the regional subsidies of Air NZ, and a shiny new 777-300 simulator. The first actual deliveries of the 777-300 order are scheduled to arrive in November 2010. There’s also a 787 simulator been ordered, but given that the plane itself is currently going through the certification process and modifications might be made, I doubt that’s due any time soon. The picture below gives you a rough idea what those simulators look like (note: this is not any of the actual Air NZ sims).

Additional to the simulators, the building caters for a quite a bit of crew training, it has theory and computer-based-training classrooms as well as crew briefing and -debriefing rooms. In preparation for the day, I had a look at the 777 flight manual and some checklists (for Flight Sim X etc) to get an idea of the cockpit and instrument layout and how things roughly work. On arrival at the sim centre, we were greeted by Joy, one of the instructors. She showed us around and then we went to the 777-200 simulator and I took control of the plane *g*. Diane jumped into the first officer’s seat and Joy started to explain the cockpit and what we’re going to do. The photo shows my side of the cockpit: Flight director to the left (it’s basically a combined artificial horizon, airspeed indicator, direction indication and also shows the altitude) then the navigation display, 3 individual instruments in a column, the Flight management computer below it and the engine displays towards the right (they’re not running yet as you can see)

cockpit

The autostart feature of the 777 is pretty cool. What it comes roughly down to – make sure breaks are set, engine is in autostart mode and provide fuel to the engine and off you go. Same for shutting it down (and that’s very similar to the type of planes I fly) – cut the fuel flow into the engine and it will shutdown. The next image shows the controls below the FMC – the big lever is thrust and to the right you can see the settings for flaps – from 1 to 30 degrees.

more cockpit

When the simulation launched we found ourselves at gate 3 of NZAA international, scheduled to take-off from Runway 23L. First interesting challenge (after starting the engines and being pushed back) – finding the correct taxiways, keep the plane on the yellow line to avoid hitting any building, car or other plane along the way and line up correctly. It was quite amazing how real those simulators feel. It takes quite a while for the 777 to overcome the intertia but after I got it rolling once, it hardly wanted to stop.

Lined up correctly, the takeoff was initiated, auto-thrust took over and soon after we reached the rotation speed of (I think) some 150 knots and off we went. We took off from 23L climbed out quite straight ahead for a short moment and then banked into a right turn for a Peeha One Alfa departure from NZAA. I found the flight director instrument helping a lot with that – awesome little thing I’d love to have in my 172 :-) Below is the ILS departure chart, having reached 3000 feet, Auckland city was already clearly coming in sight and we did a few turns and basic maneuverers to get grip of the plane.

Departure chart

Luckily Diane took videos (yay!) – here’s a video of the take off (you can also hear/see her raising the gears after takeoff):

We then programmed an ILS approach for runway 23L via the navigation point EMRAG into the flight computer and the navigation display started to show me the approach pattern (basically an arc that leads into finals for 23L) to follow. The idea of such a pattern is that the pilots ends up being on a 3-dimensional glide slope that leads directly to the touchdown point. You’re given vertical and horizontal indicators in the Flight Director screen, which is very helpful.

FD

When we entered the approach, we disconnected the autopilot and I flew the plane through the arc and on finals. My first approach became slightly wobbly at about 1000 feet – not badly though, but I had issues keeping the wings perfectly level because I lost the glide slope a few times and tried to catch up with it. When you approach the ground, the plane will very clearly call out the altitude (as in “one hundred!!!!! … fifty!!!! … thirty!!!! etc) so that the pilot is def. aware of the fact that a landing is to be expected very soon. As a consequence of my wobbly approach my first touchdown was a bit too hard, but still came in reasonably straight on the centreline and when the thrust reversers and auto-break kicked in we got to a quite quick stop.

Joy then asked me if I wanted to do another one (WHAT A QUESTION!) – sure I wanted. Actually it ended up being two more and my second and third approach were so much nicer and smother and particularly in the third I got the hang of it. The picture below is a (slighty blurry) shot of the navigation display and you can see that the turn is not a perfect arc. That’s because we started that particular approach closer to EMRAG and then it became some sort of a short-cut approach into 23L.

Post to Twitter Post to Delicious Post to Facebook Post to StumbleUpon

A visit at Air New Zealand’s Engineering Base in Auckland

This is the second post about my awesome day on Monday. After @blauerpunto and I arrived in Auckland, Mark Farley from Air NZ picked us up at the air bridge. Mark is a Flight Service Manager with Air New Zealand but also does a lot of work on the ground. One of his projects is crew management, training and planning for a project Air NZ runs together with Hawaiian Airlines (more on that further down).

We went over to the Engineering Base in Auckland which is pretty much an operation that works around the clock. We got a temporary Aviation Security ID (in form of a sticker) and met Ian Parkes, Communications Manager for Air NZ Tech Ops who gave us a tour through the different workshops and a few maintenance hangars.

Engine and wing section of ZK-OKC

The engineering crews at the base are not just taking care of Air NZ’s own planes but also contract out their services to airline partners and in some cases direct competitors. The project with Hawaiian Airlines I mentioned above for instance comprises Air NZ Engineering taking over an Hawaiian Airlines Boeing 767 plane that flies into Sydney and comes to Auckland for maintenance. After the maintenance work is done, an Air New Zealand crew takes control and ferries the plane back to Hawaii on an NZ flight number (not as a codeshare flight number). Customers might therefore get a bit of an unusual experience traveling with Air NZ pilots and cabin crew on Hawaiian metal. The cabin crew needs to be particularly trained and licensed to work on such a plane and that requires alterations to normal crew scheduling etc.

When we walked through the maintenance hangars there were an A320, a Hawaiian B767 and an AirNZ 777 around. The amount of people working on such a plane at the same time (depending on the type of maintenance) is enormous. Logistically there is also a tremendous pile of paperwork to deal with as work instructions, defects and the proper action have to be documented, done, signed-off and quality controlled. Ian said that they tried to experiment with introducing PDAs for those processes but that a paper-driven documentation with humans actually signing documents still seems to be the best option in such an environment.

In the 777 hangar I stood under ZK-OKC, the one currently being on maintenance. It’s massive. That’s already keeping in mind that other planes such as the B747 or the A380 are even larger – but it’s still massive. Actually the A380 is literally a monster against the “tiny” 777. There are quite a few interesting details to look at when you’re close to such a plane. The picture below shows one of the Rolls-Royce engines. It’s probably hard to see, but there’s a little rubber cone on top of the centre of the turbine. That’s being put in there to avoid icing – very clever engineering from Rolls Royce’s team according to Ian. An equivalent engine model from a US manufacturer just has a power-consuming heating plate in there.

Rolls Royce engine of a 777-200

It’s quite amazing to learn about the amount of stuff Air NZ can take care of themselves when it comes to repairing parts or crafting new parts. Diane pretty much fell in love with the fact that and how they create the nose cones for the planes. In the avionics lab Air NZ has setup a joint venture with one of the vendors of a lot of avionic devices and parts to again provide services for a lot of other airlines as well. There’s a quite amazing huge $6 million computer system in there that comes with a wardrobe-size section of interface bays where all sorts of devices from a variety of planes can be plugged in to simulate and replay faults.

From a business point of view, Air NZ’s Tech Ops is highly profitable. Because Air NZ is a rather small airline (and some maintenance for domestic planes is done in Christchurch and/or in the engineering bases of the smaller subsidies like Air Nelson or Eagle) the Auckland base works for pretty much all other airlines flying into Auckland international. In a lot of cases that might just mean smaller maintenance jobs and checks before a plane is returning back overseas to wherever it came from, but in some instances as above it could mean that some airlines also get major works done in Auckland.

Some 747s, parked outside the hangar

Very awesome start of the day, but stay tuned – way more to come! :-)

Post to Twitter Post to Delicious Post to Facebook Post to StumbleUpon

An awesome day with Air New Zealand

Yesterday, I had one of the most awesome days of my life. It would rate it right below the category comprising “Getting married to @blauerpunto” and “Getting permanent residency in New Zealand” and on a very similar level with stuff such as “Flying in a small airplane for the first time” and “Going solo in a small airplane for the first time”.

So – what happened? Let me briefly introduce you to the events that lead into yesterday’s trip to Auckland with and to Air New Zealand. As you all know, I’m flying quite a bit and that pretty much exclusively (well, at least to the destinations they offer) on Air New Zealand. Among being actually a really nice and friendly airline, their marketing and communications team is absolutely on top of their game and is leveraging all sorts of online and social media services. Among those is a twitter account named @airpointsfairy. She wears a cute dress, lives in a beautiful fairy land and fulfils wishes of members of Air NZ’s frequent flyer program Airpoints.

Normally members wish for an access pass for a lounge, a top up of their Airpoints$ to being able to spend them on a particular flight reward an similar thing. But before Xmas last year, the Airpointsfairy was doing a “12 days of Xmas”-themed giveaway of larger gifts. One Saturday morning, Diane woke me up saying the Airpointsfairy was giving away 2 simulator rides in Air NZ’s 777-200 simulator in Auckland. So Diane thought she actually had a good reason to wish that I got one because due to our wonderful Wellington weather it was clear that I wasn’t going to go flying in a Cessna 172 on that day (as originally planned). To fast-forward the story – I won it. Including a trip to Auckland with @blauerpunto and including a tour of Air NZ’s Engineering base in Auckland and Hangar 9 (where they secretly developed the new seats and cabins for the 777-300 and the 787 Dreamliner) in the city.

Diane already posted about the overall experience of the trip (which was just awesome) last night (make sure you scroll further down for English). So, I won’t go into all those details again, but the next few posts will be for the aviation geeks among you – more coming tonight! Just one thing in advance: Flying a jet in a simulator is freakin’ awesome. It feels quite real and flying a real jet must be even more awesome. Anyone wants to pay for my training? :-)

Post to Twitter Post to Delicious Post to Facebook Post to StumbleUpon