Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory leak caused by scala.reflect.internal.util.Statistics #7130

Closed
scabug opened this issue Feb 14, 2013 · 4 comments
Closed

Memory leak caused by scala.reflect.internal.util.Statistics #7130

scabug opened this issue Feb 14, 2013 · 4 comments
Assignees
Milestone

Comments

@scabug
Copy link

@scabug scabug commented Feb 14, 2013

In Types.scala we have the following code:

  Statistics.newView("#unique types") { if (uniques == null) 0 else uniques.size }

Let's have a closer look at Statistics.newView:

def newView(prefix: String, phases: String*)(quant: => Any): View = new View(prefix, phases, quant)

As you can see newView takes by-name argument (that in our case closes over the whole Global) and passes it to View.

The View class inherits from Quantity that is defined as follows:

  trait Quantity {
    if (prefix.nonEmpty) {
      val key = s"${if (underlying != this) underlying.prefix else ""}/$prefix"
      qs(key) = this
    }
    val prefix: String
    val phases: Seq[String]
    def underlying: Quantity = this
    def showAt(phase: String) = phases.isEmpty || (phases contains phase)
    def line = f"$prefix%-30s: ${this}"
    val children = new mutable.ListBuffer[Quantity]
  }

So we register this in global (defined in top-level object) HashMap stored in variable qs. The consequence is that even if you don't use Global it'll be still hanging there because Statistics holds reference to it. This is a memory leak that I observed while using Scala IDE where Global used for compiling the code was kept around and consumed aroung 0.5GB of heap.

@scabug
Copy link
Author

@scabug scabug commented Feb 14, 2013

Imported From: https://issues.scala-lang.org/browse/SI-7130?orig=1
Reporter: @gkossakowski
Affected Versions: 2.10.0, 2.10.1-RC1

@scabug
Copy link
Author

@scabug scabug commented Feb 14, 2013

@gkossakowski said:
Added Iulian to watchers as he might be interested in this ticket.

@scabug
Copy link
Author

@scabug scabug commented Feb 14, 2013

@gkossakowski said:
The simple solution to avoid memory leak is to turn all operations in Statistics into no-ops in case statistics is disabled.

However, the whole design is broken because it doesn't work across many Globals. Also, life cycle of that top-level object is not clear to me since you can mutate enabled flag at any time.

@scabug
Copy link
Author

@scabug scabug commented Feb 19, 2013

@scabug scabug closed this Feb 19, 2013
@scabug scabug added the critical label Apr 7, 2017
@scabug scabug added this to the 2.10.2-RC1 milestone Apr 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants