-1

I have a var object in my class which can be very big due to its large content. To cope with the size issue, once in a while I have to create a new instance of this class, where the content is pruned. This is the reason that it's a "mutable".

A high-level view of my target class is this:

class FancyClass { 
   // this element gets big, but I keep pruning it. 
   var bigObject = initialize()

   def soSth() { 
      bigObject.method1()

      // once in a while I prune this 
      bigObject = bigObject.prune() 
   }
}

bigObject is what gets big. Every few iterations, I replaced it with another object which is supposed to be smaller: bigObject = bigObject.prune().

The problem is that tracing the memory, the memory usage almost never shrinks. In fact, it consistently gets higher (instead of a little drop in the memory usage).

I suspect that after bigObject = bigObject.prune() GC does not remove the old instance. Any thoughts on this issue?

Daniel
  • 5,839
  • 9
  • 46
  • 85
  • There are a few questions about ergonomics of JVM memory management. GC is one thing, releasing system memory another. Random sample with more links. https://stackoverflow.com/q/42818515/1296806 – som-snytt Mar 17 '18 at 18:11

1 Answers1

3

There are few possibilities: a) reference to bigObject is published somewhere outside of FancyClass so gc can't collect it b) bigObject.prune is not so small as you expect c) memory issues are caused by another part of the program

The most robust and straightforward solution is to run the program under a profiler (e.g. JVisualVm) Then you can see how many instances of BigObject class you have, their size and who holds references to them.

Also it can be helpful to take 2 heap dumps of your program: after e.g. 5 minutes and after e.g. 30 minutes and compare the number/size of the objects by class. If the number of BigObject instances has grown significantly probably there is a memory leak.

simpadjo
  • 3,947
  • 1
  • 13
  • 38