0

Scala 2.11 mutable.Map is instantiating too many DefaultEntry.

Code to reproduce:

val map: mutable.Map[Int, String] = mutable.Map()
(1 to 1000000).foreach(n => map(n.toString) = s"number $n")

Here's the memory sample from visualvm: enter image description here

I wasn't expecting to see so many instances of DefaultEntry. What's the reason?

pedromorfeu
  • 1,739
  • 14
  • 18
  • it really depends a lot on what your application is doing, and the code. maybe you have an hashmap somewhere. maybe you are itereating though the HashEntries... – pedrorijo91 Nov 06 '20 at 12:59
  • If you look at the code to reproduce, it does nothing apart from creating the map. – pedromorfeu Nov 07 '20 at 14:40

1 Answers1

1

Your code is correct and instances also. Here you have 1_000_001 n and for each n you call:

map(n.toString) = s"number $n"

map(key) = value is just syntactic sugar for calling update(key, value) function.

Let's look at update implementation of mutable.Map, by default it will be HashMap:

override def update(key: A, value: B): Unit = put(key, value)

go to the put:

override def put(key: A, value: B): Option[B] = {
  val e = findOrAddEntry(key, value)
  if (e eq null) None
  else { val v = e.value; e.value = value; Some(v) }
}

protected def findOrAddEntry[B](key: A, value: B): Entry = {
  val h = index(elemHashCode(key))
  val e = findEntry0(key, h)
  if (e ne null) e else { addEntry0(createNewEntry(key, value), h); null }
}

protected def createNewEntry[B1](key: A, value: B1): Entry = {
  new Entry(key, value.asInstanceOf[B])
}

in the method createNewEntry new Entry is created. You call update on your map 1_000_001 times and key is always unique this is the reason you have 1_000_001 DefaultEntry objects.

Boris Azanov
  • 4,408
  • 1
  • 15
  • 28