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).