mirror of
https://github.com/ysoftdevs/odc-analyzer.git
synced 2026-05-08 08:53:33 +02:00
Drastically reduced memory usage, mostly using deduplication.
This commit is contained in:
25
app/com/ysoft/debug/KnownObjects.scala
Normal file
25
app/com/ysoft/debug/KnownObjects.scala
Normal file
@@ -0,0 +1,25 @@
|
||||
package com.ysoft.debug
|
||||
|
||||
import java.util
|
||||
|
||||
import com.google.caliper.memory.ObjectVisitor.Traversal
|
||||
import play.api.Logger
|
||||
|
||||
// We use Java collections because they can have the initial size configured
|
||||
case class KnownObjects(
|
||||
objSet: java.util.HashSet[Any] = new util.HashSet[Any](),
|
||||
identitiesSet: java.util.Set[Any] = java.util.Collections.newSetFromMap(new util.IdentityHashMap[Any, java.lang.Boolean]())
|
||||
){
|
||||
def visit(obj: AnyRef) = {
|
||||
val seen = !identitiesSet.add(obj)
|
||||
if(seen){
|
||||
Traversal.SKIP
|
||||
}else{
|
||||
objSet.add(obj)
|
||||
Traversal.EXPLORE
|
||||
}
|
||||
}
|
||||
|
||||
def stats = (identitiesSet.size, objSet.size)
|
||||
|
||||
}
|
||||
44
app/com/ysoft/debug/ObjectGraphDuplicityMeasurer.scala
Normal file
44
app/com/ysoft/debug/ObjectGraphDuplicityMeasurer.scala
Normal file
@@ -0,0 +1,44 @@
|
||||
package com.ysoft.debug
|
||||
|
||||
import java.util
|
||||
|
||||
import com.google.caliper.memory.ObjectVisitor.Traversal
|
||||
import com.google.caliper.memory.{Chain, ObjectExplorer, ObjectVisitor}
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
object ObjectGraphDuplicityMeasurer {
|
||||
|
||||
def measureUnique(obj: AnyRef) = {
|
||||
ObjectExplorer.exploreObject(obj, new ObjectVisitor[((Int, Int), Map[Class[_], (Int, Int)])](){
|
||||
val all = KnownObjects(
|
||||
objSet = new util.HashSet[Any](),
|
||||
identitiesSet = java.util.Collections.newSetFromMap(new util.IdentityHashMap[Any, java.lang.Boolean]())
|
||||
)
|
||||
|
||||
val classMap = mutable.Map[Class[_], KnownObjects]()
|
||||
def forClass(cl: Class[_]) = classMap.contains(cl) match{
|
||||
case true => classMap(cl)
|
||||
case false =>
|
||||
val kn = KnownObjects()
|
||||
classMap(cl) = kn
|
||||
kn
|
||||
}
|
||||
|
||||
override def visit(chain: Chain): Traversal = {
|
||||
val value = chain.getValue
|
||||
if(chain.isPrimitive || value == null || classOf[Enum[_]].isAssignableFrom(chain.getValueType) || value.isInstanceOf[Class[_]] ){
|
||||
Traversal.SKIP
|
||||
}else{
|
||||
val res = all.visit(value)
|
||||
forClass(value.getClass).visit(value)
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
override def result() = (all.stats, classMap.toMap.mapValues(_.stats).map(identity))
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user