import jdk.jfr.consumer.RecordedClass
import jdk.jfr.consumer.RecordedEvent
import jdk.jfr.consumer.RecordingStream
import java.nio.ByteBuffer
import java.time.Duration
import kotlin.system.exitProcess
fun main(args: Array<String>) {
// OOME を発行させるスレッド
Thread {
Thread.sleep(1000)
val bbList = mutableListOf<ByteBuffer>()
while (true) {
try {
val bb = ByteBuffer.allocateDirect(Int.MAX_VALUE)
bbList.add(bb)
} catch (e: Error) {
println("Caught $e")
}
}
}.start()
// OOME があったら harakiri する。
RecordingStream().use { rs ->
rs.enable("jdk.JavaExceptionThrow").withPeriod(Duration.ofSeconds(1))
rs.onEvent("jdk.JavaExceptionThrow") { event: RecordedEvent ->
val message = event.getString("message")
val thrownClass = event.getValue<RecordedClass>("thrownClass")
if (thrownClass.name == "java.lang.OutOfMemoryError" && message.startsWith("Cannot reserve")) {
println("Caught OutOfMemoryError! $event")
exitProcess(4)
}
}
println("Starting RecordingStream")
rs.start()
}
}