Can someone help me figure out what I need to do to call the function getCollectionCount()
from this java library?
What do I need to import, what do I need to add to my build.sbt etc?
Can someone help me figure out what I need to do to call the function getCollectionCount()
from this java library?
What do I need to import, what do I need to add to my build.sbt etc?
This is what I’ve tried, but it doesn’t work.
import java.lang.management._
val beans: Array[GarbageCollectorMXBean] = ManagementFactory.getGarbageCollectorMXBeans().toArray
val gcCount0 = beans(0).getCollectionCount()
val gcTime0 = beans(0).getCollectionTime()
println(s"gcCount0=$gcCount0 gcTime0=$gcTime0")
Here is the message I get from IntelliJ
And I get the following compiler error. Which I don’t understand. Do I really need to use a wildcard such as _ >: java.lang.management.GarbageCollectorMXBean
from SLS 3.2.10
My feeling is that this 3.2.10 error is a red herring, that I’m simply not accessing the getCollectionCount
and getCollectionTime
methods correctly.
Error:(198, 99) type mismatch;
found : Array[Object]
required: Array[java.lang.management.GarbageCollectorMXBean]
Note: Object >: java.lang.management.GarbageCollectorMXBean, but class Array is invariant in type T.
You may wish to investigate a wildcard type such as `_ >: java.lang.management.GarbageCollectorMXBean`. (SLS 3.2.10)
val beans: Array[GarbageCollectorMXBean] = ManagementFactory.getGarbageCollectorMXBeans().toArray
Your problem is actually with the java.util.List
API. Its toArray
method returns a Array[AnyRef]
.
You can use this other toArray
method, which I find quite ridiculous to be honest:
ManagementFactory
.getGarbageCollectorMXBeans()
.toArray(Array.empty[GarbageCollectorMXBean])
Or you can move to the Scala universe where toArray
does what one would expect:
import scala.jdk.CollectionConverters._
ManagementFactory
.getGarbageCollectorMXBeans()
.asScala
.toArray
thanks. Is scala.jdk
correct or a typo? My system doesn’t find it. Maybe I need to update my build.sbt
file?
In Scala 2.13 that should work.
In older versions it’s scala.collection.JavaConverters
.
So, here is the code I’m running. It seems to work, although I’m still analyzing the results.
As I’m not sure how many beans I will have (perhaps just 1), I’m folding over the results to add up all of them. That’s probably fine for the gc-count, but perhaps dubious for the time. Perhaps time should be maximized rather than summed???
import java.lang.management._
// Thanks Jasper M for the following recipe.
// https://users.scala-lang.org/u/jasper-m
// https://users.scala-lang.org/t/how-to-call-a-function-from-a-java-library/5722/2
val beans: Array[GarbageCollectorMXBean] = ManagementFactory
.getGarbageCollectorMXBeans()
.toArray(Array.empty[GarbageCollectorMXBean])
def gcCount(): Long = beans.foldLeft(0L) { (acc, b) => b.getCollectionCount() + acc }
def gcTime(): Long = beans.foldLeft(0L) { (acc, b) => b.getCollectionTime() + acc }
val gcCount0 = gcCount().toDouble
val gcTime0 = gcTime().toDouble
val (colorization, bdd) = graphToBdd(List(start), uniGraph, biGraph, numNodes,
(n: Double, size: () => Double) => {
newGcCount(n, gcCount() - gcCount0)
newGcTime(n, gcTime() - gcTime0)
newSize(n, size())
val (hashSize, numAllocations) = Bdd.getBddSizeCount()
newHashSize(n, hashSize.toDouble)
newNumAllocations(n, numAllocations.toDouble)
},
differentColor,
fold = fold)
I have 2. Probably one is for young generation and another one is for old generation. For information about objects’ generations look at Tracing garbage collection - Wikipedia
Time should be summed if you want total time. In most GCs young and old GC cycles don’t overlap.