Memory Leaks: Part II – variables scope leak
In part II of my memory leak posts, I will attempt to demonstrate a simple example of how the CFML runtime engine can cause memory leaks. If you would like to know more about the tools I used to identify the problem, or would like to follow along with the example you should take a look at my previous post, "ColdFusion Memory Leaks: Part I – profiler introduction"
For those of you that have ever experienced memory leaks, have there been cases where you have been convinced that the problem is not your code? Well, you may actually be right. This example will show a very simple case, then I will try to build on this to show a more problematic example in my next post.
The first part of the example is to create a simple .cfc. This cfc will have 2 methods: init() which returns itself, and doSomething() which will return an array of 100 instances of itself.
The next part of the example will be a simple cfm file. This file will create 1 instance of the test.cfc and load it into application scope, then it will call the doSomething() function and set the result to a local variable that resides in variables scope.
foo is an array of #arrayLen(foo)# elements
What should we expect from this example? Well, we should have 1 instance of test.cfc persisted in the heap. We will create 100 references to test.cfc, but those should only exist in the heap until the end of the request. The garbage collector should pick them up immediately, as all references should only exist for the request.
Now, to show the results of the test, I created a movie that will show the behavior, watch it to see what actually happens.
What happened? As you can see, 101 instances were persisted in the heap, and not released. These instances will live for the life of the application and NOT for the life of the request as intended. In this case we should only see 1 instance of the cfc in the heap. Here are some of the behaviors I observed.
- references to objects created in application scope will be kept alive if they are
set to a reference in the variables scope.
- Setting the variable in variables scope to empty string " "
will destroy the reference.
- Setting the reference in request scope will clean up the reference correctly.
- Calling structClear(variables)
in onRequestEnd.cfm will destroy unwanted references tied to variables scope
- The reference retained in the variables scope only seems
to apply to the last request to the.cfm file (will not grow)
As you can see, this isn ‘t a horrible memory leak because it won’t grow continually,
but it could cause unwanted objects to be persisted in memory. This IS a simple example, and
I’m working to create a similar, but more complex example to build on this that will show that cfc references can grow in memory on every request. Stay Tuned.