Does the problem happen if you just print nodes.size? Or, perhaps, print nodes.size twice?
running it with -Xms4096m -Xmx 4096m it works fine for me (both with line 24 commented and not). 2gb heap died with out of memory errors. I'm using a 25mb txt file called mthesaur.txt that I grabbed from project gutenberg. Scala 2.9.2, jvm 1.7.05
Will try to make time this afternoon.
Instead of doing this: val graph = Array.ofDim[Int](nodes.size, nodes.size)
./src/library/scala/Symbol.scala: import java.util.WeakHashMap./src/library/scala/Symbol.scala: private val map = new WeakHashMap[K, WeakReference[V]]
Hopefully not the one that encourages enormous memory leaks?
val nodes = new collection.mutable.HashMap[Symbol, Integer]var syms = List.empty[Symbol]...chunks foreach { node =>nodes += (node -> nodes.size)syms ::= node}probably fixes it
You are entirely right, for some reason I'd decided that the hashmap wasn't keeping the key, despite the fact that that's stupid :PI now don't see why the symbols get collected. You've kept a reference to them in your map, so they should be strongly reachable. I'm clearly missing an important piece of this puzzle somewhere...
Does replacing Symbol with String remove the problem? That would change the memory footprint, so it could _mask_ the problem, but my best bet lies that way.
Except that the symbol itself has a strong reference to the string, and we have a strong reference to that symbol inside the hashmap...
import io.Sourceobject HashMapBug {def main(args: Array[String]) {load("mobythes.aur")}def load(fileName: String) {val nodes = new collection.mutable.ListBuffer[Symbol]Source.fromFile(fileName).getLines foreach { line =>nodes += (line.split(",") map { s => Symbol(s) }).head
}val graph = Array.ofDim[Int](nodes.size, nodes.size)
nodes foreach { node =>if (!(Symbol(node.name) eq node))println(node)}}}
pauls-macbook:hashmap-bug paul$ sbt runDetected sbt version 0.12.0Using /Users/paul/.sbt/0.12.0 as sbt dir, -sbt-dir to override.[info] Set current project to hashmap-bug (in build file:/Users/paul/personal/hashmap-bug/)[info] Running HashMapBug'bookdealer'buccaneer'chap'clitoris'concatenate'conserve'cooking'counterproductive'crease'crystal ball'culminating'cushion'damsel'deafening'defrock'disenthrone'dishwater'disqualify'drink up'drip'dropout'echelon'embossed'equerry'Eucharist'excerpt'expositor'farm out'fifth'frowzy'frustrated'gabby'good taste'headdress'hoodwink'incertitude'incommutable'intensive care'intentionally'interdict'jenny'lea'lodger'look back'lordliness'marine animal'mendicancy'missilery'monaural system'moneylender'morality'mud flat'muggy'muster out'nares'nascent'nerve center'nightmare'noncombatant'out of character'out of reach'outreach'overhanging'palm oil'parolee'persons'piazza'plain English'plasticity'plebeian'plebiscite'posted'pour forth'prat'precinct'prevaricate'puce'punish'purifier'purposely'putrefy'rabbinate'raccoon'restrictive'rotor'rub down'sapphire'scathe'scram'scrap'shamrock'shoran'shotgun'sizzle'sledgehammer'smitten'smooth sailing'sniff'social outcast'sooner'sparse'specious reasoning'streetcar line'subduer'surgical'Tartuffe'tear apart'throwaway'topknot'treasure trove'tyrant'ugliness'uncork'unobtainable'unsexed'untalkative'urbanite'variety'view'vine'wash down'wavering'well-planned'whoosh'womanish'womanize'wooded'worldly'yip[success] Total time: 6 s, completed Nov 23, 2012 10:00:47 PM
Welcome to Scala version 2.10.0-RC3 (OpenJDK 64-Bit Server VM, Java 1.7.0_09).Type in expressions to have them evaluated.Type :help for more information.scala> var name = "foo" + 1name: String = foo1scala> var s1 = Symbol(name)s1: Symbol = 'foo1scala> s1 = nulls1: Symbol = nullscala> System.gcscala> val s2 = Symbol("foo1")s2: Symbol = 'foo1scala> name = nullname: String = nullscala> System.gcscala> val s3 = Symbol("foo1")s3: Symbol = 'foo1scala> s2 eq s3res2: Boolean = false