Add Kotlin daemon memory usage into build report

#KT-56211: Fixed
This commit is contained in:
nataliya.valtman
2023-02-10 12:45:32 +01:00
committed by Space Team
parent f0fba7be64
commit c16dabba1f
5 changed files with 21 additions and 5 deletions
@@ -15,6 +15,9 @@ enum class BuildPerformanceMetric(val parent: BuildPerformanceMetric? = null, va
BUNDLE_SIZE(readableString = "Total size of the final bundle", type = ValueType.BYTES),
DAEMON_INCREASED_MEMORY(readableString = "Increase memory usage", type = ValueType.BYTES),
DAEMON_MEMORY_USAGE(readableString = "Total memory usage at the end of build", type = ValueType.BYTES),
COMPILE_ITERATION(parent = null, "Total compiler iteration", type = ValueType.NUMBER),
ANALYZED_LINES_NUMBER(parent = COMPILE_ITERATION, "Number of lines analyzed", type = ValueType.NUMBER),
CODE_GENERATED_LINES_NUMBER(parent = COMPILE_ITERATION, "Number of lines for code generation", type = ValueType.NUMBER),
@@ -39,7 +42,7 @@ enum class BuildPerformanceMetric(val parent: BuildPerformanceMetric? = null, va
START_TASK_ACTION_EXECUTION(readableString = "Start time of task action", type = ValueType.MILLISECONDS),
CALL_KOTLIN_DAEMON(readableString = "Finish gradle part of task execution", type = ValueType.NANOSECONDS),
CALL_WORKER(readableString = "Worker submit time", type = ValueType.NANOSECONDS),
START_WORKER_EXECUTION(readableString = "Start time of werker execution", type = ValueType.NANOSECONDS),
START_WORKER_EXECUTION(readableString = "Start time of worker execution", type = ValueType.NANOSECONDS),
START_KOTLIN_DAEMON_EXECUTION(readableString = "Start time of kotlin daemon task execution", type = ValueType.NANOSECONDS),
FINISH_KOTLIN_DAEMON_EXECUTION(readableString = "Finish kotlin daemon execution", type = ValueType.MILLISECONDS),
;
@@ -81,7 +81,7 @@ interface CompileService : Remote {
fun checkCompilerId(expectedCompilerId: CompilerId): Boolean
@Throws(RemoteException::class)
fun getUsedMemory(): CallResult<Long>
fun getUsedMemory(withGC: Boolean = true): CallResult<Long>
@Throws(RemoteException::class)
fun getDaemonOptions(): CallResult<DaemonOptions>
@@ -723,8 +723,8 @@ class CompileServiceImpl(
(compilerId.compilerClasspath.all { expectedCompilerId.compilerClasspath.contains(it) }) &&
!classpathWatcher.isChanged
override fun getUsedMemory(): CompileService.CallResult<Long> =
ifAlive { CompileService.CallResult.Good(usedMemory(withGC = true)) }
override fun getUsedMemory(withGC: Boolean): CompileService.CallResult<Long> =
ifAlive { CompileService.CallResult.Good(usedMemory(withGC = withGC)) }
override fun shutdown(): CompileService.CallResult<Nothing> = ifAliveExclusive(minAliveness = Aliveness.LastSession) {
shutdownWithDelay()
@@ -212,6 +212,9 @@ internal class GradleKotlinCompilerWork @Inject constructor(
log.debug("Kotlin compile daemon JVM options: ${jvmOpts.get().mappers.flatMap { it.toArgs("-") }}")
}
}
val memoryUsageBeforeBuild = daemon.getUsedMemory(withGC = true).takeIf { it.isGood }?.get()
val targetPlatform = when (compilerClassName) {
KotlinCompilerClass.JVM -> CompileService.TargetPlatform.JVM
KotlinCompilerClass.JS -> CompileService.TargetPlatform.JS
@@ -231,6 +234,16 @@ internal class GradleKotlinCompilerWork @Inject constructor(
bufferingMessageCollector.flush(messageCollector)
throw e
} finally {
val memoryUsageAfterBuild = daemon.getUsedMemory(withGC = false).takeIf { it.isGood }?.get()
if (memoryUsageAfterBuild == null || memoryUsageBeforeBuild == null) {
log.debug("Unable to calculate memory usage")
} else {
metrics.addMetric(BuildPerformanceMetric.DAEMON_INCREASED_MEMORY, memoryUsageAfterBuild - memoryUsageBeforeBuild)
metrics.addMetric(BuildPerformanceMetric.DAEMON_MEMORY_USAGE, memoryUsageAfterBuild)
}
// todo: can we clear cache on the end of session?
// often source of the NoSuchObjectException and UnmarshalException, probably caused by the failed/crashed/exited daemon
// TODO: implement a proper logic to avoid remote calls in such cases
@@ -261,7 +261,7 @@ abstract class BuildReportsService : BuildService<BuildReportsService.Parameters
when (key.type) {
ValueType.BYTES -> "${key.readableString}: ${formatSize(value)}"
ValueType.MILLISECONDS -> DATE_FORMATTER.format(value)
else -> "${key.readableString}: $value}"
else -> "${key.readableString}: $value"
}
}
timeData.union(perfData).joinTo(readableString, ",", "Performance: [", "]")