Constructor memory leaks

Yesterday I fixed a nasty memory leak in our PushServer which is written in Scala. As so happens with all the memory leaks, application was  running smoothily in test mode and just when I deployed in production it bombed within hours of launching the application.  The problem was with following bit of code:

class Quote(dataHash: Map[Int,Any],oldQuote: Quote) extends AmtdStockData {
  val symbol: String = dataHash.getOrElse(0,oldQuote.symbol)
  val bid: Float = dataHash.getOrElse(1,oldQuote.bid)
  val ask: Float = ....
}

Above code defines Quote class, the constructor of class takes a data Map as an argument and old quote for the same symbol. Class populates its field from data Map, but if a certain field is not found in the Map, it uses the field’s value from oldQuote. The Quote class basically works around the problem from data providers which send only updated fields for Level 1 quote.

Probably you have guessed by now, the problem with above code is that memory that is held by old quotes are never freed, because newer quotes always keep a reference to old quote values.

I can probably say, similar logic wouldn’t have created problems with Java or C++, but since constructor arguments are automatically taken as class fields in scala, we have a problem. The ability to pass arguments while defining a class and using it as a constructor is a life saver.It helps in avoiding placeholder field declaration which will be later populated through constructor or another method call as done in Java/C++.

But apparently, in this particular case I needed old ugly way back and hence new code is:

class Quote extends AmtdStockData {
  var symbol: String = _
  var bid: Float = _
  var ask: Float = _
  def populateValues(dataHash: Map[Int,Any],oldQuote: Quote) = {
    // populate above fields
  }
}

Above class design solves the problem at the expense of using “var”.Its not ideal, but I am scouting for ideas if the class can be designed in any other way!

Update: Turns out compiler usually doesn’t emit field for constructor parameter unless parameter is accessed by an instance method/inner class. In above case, getOrElse creates an anonymous inner class and hence compiler emits a field for oldQuote and its never garbage collected.

One thought on “Constructor memory leaks

Leave a Reply

Your email address will not be published. Required fields are marked *