scalaplayframeworkplayframework-2.5

Troubleshooting "Out of Memory Error: Metaspace" in Play for Scala


While working in development mode in Play for Scala (2.5.x), after around three hours of changing code and hot-deploying, Play hungs with the error java.lang.OutOfMemoryError: Metaspace.

After some research, the problem seems to be that the application instantiates Java objects (such as factories and connections) that Play is not aware of, and when Play restarts these objects stay in memory causing leaks. The solution is to clean up components when Play shuts down as explained here, or to destroy them after they are used.

The problem is that I clean up all these objects and still get OutOfMemoryError. I tried with Java's jconsole to find out what classes are creating the leak and how much memory they are taking, but couldn't find much. Any ideas how to deal with this situation? I don't want to simply increase memory without knowing what's going on.

PS: This seems to be a common issue, it would be great if Play itself provided the tools to detect the problem.


Solution

  • Unfortunately, this problem seems unevitable, currently. Although, it got better in Play 2.6, I still run into this.

    And this has nothing to do with components not getting cleaned up, the metaspace is the place where classes are loaded. Play (dynamically) creates a lot of classes (e.g. anonymous classes) when compiling and each of those classes adds to the metaspace, which eventually gets filled up.

    My suggestion would be to just increase the -XX:MaxMetaspaceSize until you can work for a few hours without this exception. Then, restart sbt once in a while. I use 500 MB currently, which seems to be fine (it is usually 128MB with the SBT launcher):

    sbt -J-XX:MaxMetaspaceSize=500m
    

    This is usually no problem in production, since you have a fixed number of classes loaded (no compilation in production).