RE: [coldbox:8490] Re: WireBox notes

I never got a reply on where I left this discussion a couple weeks ago so I’m bringing it up again. I have run some tests with WireBox providers inside of ColdBox while introspecting the contents of my Java heap with jRockit Mission Control Memleak Tester as well as digging through a heap dump of my JVM in the Ecliple Memory Analyzer Tool. I beleive I have confirmed my suspicion below that the current implementation of providers and provider methods (which keeps a hard reference to the injector that spawned it) can in fact widen the scope of the ENTIRE ColdBox framework and everything in it thus creating a memory leak. The scenario can be easily produced with a component that injects a provider with a property like so:

I placed the property above into my user object which is fitting since my user object is normally persisted in both application and session scopes for various uses.

Then I set up a simple test handler with the following code that creates an instance of a user object (with its provider object injected by WireBox) and places a reference to that object in the application scope.

<cfset user = getPlugin(“beanFactory”).getModel(“user”)>
<cfset application[getTickCount()] = user>

I then called that handler 20 times with ?fwreinit=1 in the URL. Obviously you won’t blatantly reinit that often at once in production, but over the course of several weeks my app is usually reinitted every few days for small hotfixes that get pushed so it’s a realistic example of what might happen in an app over time.

That test created 20 user objects in my application scope, each of which had hard references to a separate provider object which had hard references to the 20 different injectors that created them, which in turn had hard references to the 20 different ColdBox frameworks that existed over the life of my test. I will attempt to attach the screen shot that shows jRockit displaying that I have 20 instances of the ColdBox controller still in memory. The ENTIRE framework is being held in memory 20 times by the providers and not allowed to be garbage collected. This includes all plugins, handlers, interceptors, wirebox mappings… you name it.

Memory-wise, I’m getting lucky right now. According to the Memory analyzer tool, the ColdBox controller only retains 2 MB in the heap for my app (which means I had only leaked 38 Megs), but the foundation of my position is that all those CFC’s shouldn’t have their scope widened in the first place.

I will reiterate my suggestion which is to make the providers an island to themselves with no hard references to the rest of the framework (including the injector). If the providers and components who host provider methods are loaded with the scopeRegistration information they will be able to find the current injector in scope without having any reference to the injector that created them.

Another reason why this would be useful would be so someone could safely call duplicate() on a component if all the dependencies were injected as providers. I don’t have a real-life need for that right now (mostly because I’ve made it a habit to code around that), but it’s been something I always wished I could do.

I can send a pull request of my suggested way of solving providers in a way that does not extend the scope of the injector and all it references if you like.

Thanks!

~Brad

this is definitely interesting brad,

  1. Can you show us how to setup all the tests and tools so we can make this part of our build process
  2. Have you tried the different approach? What results do you get?
  3. You rock!

Luis

Luis F. Majano
President
Ortus Solutions, Corp

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

Brad,

I did a POC and all tests and apps work. Can you try again, I just re-committed this to github.

Thanks

Luis F. Majano
President
Ortus Solutions, Corp

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

1) Can you show us how to setup all the tests and tools so we can make this part of our build process

Luis, the code is really nothing more than I had in my post. Setting
up JRockit Mission Control is a little more involved and requires you
replace your JVM. The Tool is an eclipse-based application that
connects to any running JRockit JVM to collected debugging data. Here
is a very good post about setting it up for CF:
http://www.ghidinelli.com/2009/07/16/finding-memory-leaks-coldfusion-jvm

As far as automating this type of test, I'm not sure how you would go
about doing that unless the JRockit JVM has an API you can call within
the application you are monitoring.

2) Have you tried the different approach? What results do you get?

When I don't place references to the injector into the provider OR
components who are hosting provider methods, old instances of the
ColdBox framework are properly collected from memory as they go out of
scope.