Scala 中的 DefaultEntry 实例过多 mutable.Map
Too many instances of DefaultEntry in Scala mutable.Map
Scala 2.11 mutable.Map
实例化太多 DefaultEntry
。
重现代码:
val map: mutable.Map[Int, String] = mutable.Map()
(1 to 1000000).foreach(n => map(n.toString) = s"number $n")
这是来自 visualvm 的内存示例:
我没想到会看到这么多 DefaultEntry
。什么原因?
你的代码和实例也是正确的。这里有 1_000_001 n
并且对于每个 n
你调用:
map(n.toString) = s"number $n"
map(key) = value
只是调用 update(key, value)
函数的语法糖。
让我们看看 update
实现 mutable.Map
,默认情况下它将是 HashMap
:
override def update(key: A, value: B): Unit = put(key, value)
转到 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])
}
在方法createNewEntry
中创建了new Entry
。您在 map
1_000_001 次上调用 update
并且 key
始终是唯一的,这就是您拥有 1_000_001 DefaultEntry
个对象的原因。
Scala 2.11 mutable.Map
实例化太多 DefaultEntry
。
重现代码:
val map: mutable.Map[Int, String] = mutable.Map()
(1 to 1000000).foreach(n => map(n.toString) = s"number $n")
这是来自 visualvm 的内存示例:
我没想到会看到这么多 DefaultEntry
。什么原因?
你的代码和实例也是正确的。这里有 1_000_001 n
并且对于每个 n
你调用:
map(n.toString) = s"number $n"
map(key) = value
只是调用 update(key, value)
函数的语法糖。
让我们看看 update
实现 mutable.Map
,默认情况下它将是 HashMap
:
override def update(key: A, value: B): Unit = put(key, value)
转到 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])
}
在方法createNewEntry
中创建了new Entry
。您在 map
1_000_001 次上调用 update
并且 key
始终是唯一的,这就是您拥有 1_000_001 DefaultEntry
个对象的原因。