Saturday, July 12, 2008

Memory leak when using external configuration with Grails?

Reported as Jira issue: http://jira.codehaus.org/browse/GRAILS-3252


Few days ago I added some changes to grails tutorials and suddenly it started to fail due the out of memory error. After some investigation this is my conclusion.

It seems that there is a memory leak when using external configuration file to handle certain parts of your grails application. This happened to me with Grails version 1.0 and I am able to repeat it on Axis delivered with Grails and Tomcat 5. I didn't tried with other jsp containers.

Follows short description how to create simple application to reproduce this bug. I use tag lib and didn't try if the same thing happens without tag lib.

Create new grails application: grails create-app memory-leak.

Then create new tag lib MemoryLeakTagLib.groovy. Content of this tag lib is:

class MemoryLeakTagLib {
def displayExternal = {attrs, body ->
if (grailsApplication.config.t1.value) {
out << body()
}
if (grailsApplication.config.t2.value) {
out << body()
}
if (grailsApplication.config.t3.value) {
out << body()
}
if (grailsApplication.config.t4.value) {
out << body()
}
if (grailsApplication.config.t5.value) {
out << body()
}
if (grailsApplication.config.t6.value) {
out << body()
}
if (grailsApplication.config.t7.value) {
out << body()
}
if (grailsApplication.config.t8.value) {
out << body()
}
}
}

Then create controller: grails create-controller home.

Content of the controller is:

class HomeController {
def index = {
render (view:'home')
}
}

Now create home.gsp file within folder views/home/.

Content of the home.gsp is:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="layout" content="main" />
<title>Memory leak</title>
</head>
<body>
Will same situation repeat?
<g:displayExternal>
a
</g:displayExternal>
<g:displayExternal>
a
</g:displayExternal>
<g:displayExternal>
a
</g:displayExternal>
<g:displayExternal>
a
</g:displayExternal>

</body>
</html>

Now in your HOME/.grails directory create file memory-leak-config.groovy file with the following content:

t1 {
value=true
}

t2 {
value=true
}

t3 {
value=true
}

t4 {
value=true
}

t5 {
value=true
}
t6 {
value=true
}
t7 {
value=true
}
t8 {
value=true
}

Now update Config.groovy file to also read external configuration files. Snippet how it should look like is:

 grails.config.locations = ["file:${userHome}/.grails/${appName}-config.groovy"]


if(System.properties["${appName}.config.location"]) {
grails.config.locations << "file:" + System.properties["${appName}.config.location"]
}

Now if I didn't forget some file change you should be able to start application. Open browser and point it to: http://localhost:8080/memory-leak/home First you will notice is that page is loading very long. Then while monitoring memory consumption of Tomcat or Axis refresh page few times. You will see that memory consumption is increasing. And it is never returned to the initial state. If you refresh this page constantly for 10 minutes you should run out of memory.

Well, if you didn't visit grails tutorials yet, you can do it now. It already can stand more than 80 hits (it was running out of memory after 80 hits).

6 comments:

board tc said...

Has a Jira been created for this?

jan said...

No. I didn't create Jira issue.

board tc said...

I'm not sure the purpose of the blog post as it does not provide a solution I think. The issue may be better served by posting to the grails mailing list.

jan said...

I agree that blog is probably wrong place to post a bug. I should post it to the mailing list or add it into Jira. I can added into Jira if possible as soon as I have time. I am currently at the customer side and don't want to search now how to report new bug and I am not sure if I can report new bug nor set the priority. If you think it is better to post it on mailing list just do it or you can directly report the bug. I don't have any problem with it.

Sorry, but my intentions were only good.

board tc said...

Thanks for researching this issue and letting me know about it. I am wondering if it's the reason I keep running out of memory - this is the reason I am interested in people knowing about it!

I am a humble grails foot soldier such as yourself and have no involvement with the project. It is very easy to create a jira issue and mark the matter as minor/major, anyone can do it, you create a jira login quickly at http://jira.codehaus.org/secure/Signup!default.jspa. A Jira login allows you to track any issues, etc, with all codehaus projects such as grails, groovy, greclipse...

I would suggest a post to the mailing list with a quick summary of what you have found with a link to your detailed blog post. Just my 2 cents.

jan said...

I created Jira issue and posted details about bug on mailing list.

Thanks for the advice. I must agree that my approach was wrong.

Jan