From 6601b8b62ccd58b8d538cfe543166ecf2c4ecc29 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 24 Jan 2022 16:23:16 +0100 Subject: [PATCH] Write snapshot by chunks in ProfilingCompilerPerformanceManager.dumpProfile To prevent OutOfMemoryError from converting the whole string to byte array, in case the snapshot is very big (see KT-51058). Also, remove 'framebuf' option from -Xprofile help, since async-profiler 2.0+ has unlimited frame buffer. --- .../cli/common/arguments/K2JVMCompilerArguments.kt | 2 +- .../profiling/ProfilingCompilerPerformanceManager.kt | 10 ++++++++-- compiler/testData/cli/jvm/extraHelp.out | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt index 84368502365..0927fb9f5ac 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt @@ -446,7 +446,7 @@ Also sets `-jvm-target` value equal to the selected JDK version""" description = "Debug option: Run compiler with async profiler and save snapshots to `outputDir`; `command` is passed to async-profiler on start.\n" + "`profilerPath` is a path to libasyncProfiler.so; async-profiler.jar should be on the compiler classpath.\n" + "If it's not on the classpath, the compiler will attempt to load async-profiler.jar from the containing directory of profilerPath.\n" + - "Example: -Xprofile=/async-profiler/build/libasyncProfiler.so:event=cpu,interval=1ms,threads,start,framebuf=50000000:" + "Example: -Xprofile=/async-profiler/build/libasyncProfiler.so:event=cpu,interval=1ms,threads,start:" ) var profileCompilerCommand: String? by NullableStringFreezableVar(null) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/profiling/ProfilingCompilerPerformanceManager.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/profiling/ProfilingCompilerPerformanceManager.kt index cf93d8a549d..29b32205cab 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/profiling/ProfilingCompilerPerformanceManager.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/profiling/ProfilingCompilerPerformanceManager.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.cli.common.profiling import org.jetbrains.kotlin.cli.common.CommonCompilerPerformanceManager import java.io.File +import java.io.FileOutputStream import java.text.SimpleDateFormat import java.util.* @@ -43,7 +44,12 @@ class ProfilingCompilerPerformanceManager( private fun dumpProfile(postfix: String) { outputDir.mkdirs() val outputFile = outputDir.resolve("snapshot-${formatter.format(runDate)}-$postfix.collapsed") - outputFile.writeText(profiler.execute("collapsed")) + val profile = profiler.execute("collapsed") + FileOutputStream(outputFile).use { out -> + for (chunk in profile.chunkedSequence(1 shl 20)) { + out.write(chunk.toByteArray(Charsets.UTF_8)) + } + } active = false } @@ -63,4 +69,4 @@ class ProfilingCompilerPerformanceManager( return ProfilingCompilerPerformanceManager(path, command, File(outputDir)) } } -} \ No newline at end of file +} diff --git a/compiler/testData/cli/jvm/extraHelp.out b/compiler/testData/cli/jvm/extraHelp.out index 7ef113e9e23..ccf32fe6569 100644 --- a/compiler/testData/cli/jvm/extraHelp.out +++ b/compiler/testData/cli/jvm/extraHelp.out @@ -106,7 +106,7 @@ where advanced options include: Debug option: Run compiler with async profiler and save snapshots to `outputDir`; `command` is passed to async-profiler on start. `profilerPath` is a path to libasyncProfiler.so; async-profiler.jar should be on the compiler classpath. If it's not on the classpath, the compiler will attempt to load async-profiler.jar from the containing directory of profilerPath. - Example: -Xprofile=/async-profiler/build/libasyncProfiler.so:event=cpu,interval=1ms,threads,start,framebuf=50000000: + Example: -Xprofile=/async-profiler/build/libasyncProfiler.so:event=cpu,interval=1ms,threads,start: -Xrepeat= Debug option: Repeats modules compilation times -Xsam-conversions={class|indy} Select code generation scheme for SAM conversions. -Xsam-conversions=indy Generate SAM conversions using `invokedynamic` with `LambdaMetafactory.metafactory`. Requires `-jvm-target 1.8` or greater.