From d80a463735979e9c25a8a54122c31feb7b8c8ebd Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Mon, 29 May 2017 00:25:41 +0300 Subject: [PATCH] Report memory usage only when system property is set This improves performance of Gradle builds with debug logging (--debug), because System.gc is now forced only when the system property 'kotlin.gradle.test.report.memory.usage' is set. #KT-17960 fixed --- .../kotlin/gradle/KotlinGradlePluginIT.kt | 10 +++++--- .../plugin/KotlinGradleBuildServices.kt | 24 +++++++++---------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt index a6c32116c43..4083eab903a 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt @@ -81,6 +81,7 @@ class KotlinGradleIT: BaseGradleIT() { assertFileExists("build/classes/main/META-INF/kotlinProject_main.kotlin_module") assertReportExists() assertContains(":compileKotlin", ":compileTestKotlin") + assertNotContains("Forcing System.gc") } project.build("build") { @@ -99,9 +100,11 @@ class KotlinGradleIT: BaseGradleIT() { val userVariantArg = "-Duser.variant=$VARIANT_CONSTANT" val MEMORY_MAX_GROWTH_LIMIT_KB = 500 val BUILD_COUNT = 15 + val reportMemoryUsage = "-Dkotlin.gradle.test.report.memory.usage=true" + val options = BaseGradleIT.BuildOptions(withDaemon = true) fun exitTestDaemon() { - project.build(userVariantArg, "exit", options = BaseGradleIT.BuildOptions(withDaemon = true)) { + project.build(userVariantArg, reportMemoryUsage, "exit", options = options) { assertFailed() assertContains("The daemon has exited normally or was terminated in response to a user interrupt.") } @@ -110,9 +113,10 @@ class KotlinGradleIT: BaseGradleIT() { fun buildAndGetMemoryAfterBuild(): Int { var reportedMemory: Int? = null - project.build(userVariantArg, "clean", "build", options = BaseGradleIT.BuildOptions(withDaemon = true)) { + project.build(userVariantArg, reportMemoryUsage, "clean", "build", options = options) { assertSuccessful() - val matches = "\\[PERF\\] Used memory after build: (\\d+) kb \\(difference since build start: ([+-]?\\d+) kb\\)".toRegex().find(output) + val matches = "\\[KOTLIN\\]\\[PERF\\] Used memory after build: (\\d+) kb \\(difference since build start: ([+-]?\\d+) kb\\)" + .toRegex().find(output) assert(matches != null && matches.groups.size == 3) { "Used memory after build is not reported by plugin" } reportedMemory = matches!!.groupValues[1].toInt() } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleBuildServices.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleBuildServices.kt index ac6d2dc122f..891990b4ebd 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleBuildServices.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleBuildServices.kt @@ -37,6 +37,8 @@ internal class KotlinGradleBuildServices private constructor(gradle: Gradle): Bu companion object { private val CLASS_NAME = KotlinGradleBuildServices::class.java.simpleName const val FORCE_SYSTEM_GC_MESSAGE = "Forcing System.gc()" + const val SHOULD_REPORT_MEMORY_USAGE_PROPERTY = "kotlin.gradle.test.report.memory.usage" + val INIT_MESSAGE = "Initialized $CLASS_NAME" val DISPOSE_MESSAGE = "Disposed $CLASS_NAME" val ALREADY_INITIALIZED_MESSAGE = "$CLASS_NAME is already initialized" @@ -68,6 +70,7 @@ internal class KotlinGradleBuildServices private constructor(gradle: Gradle): Bu private var startMemory: Long? = null private val workingDir = File(gradle.rootProject.buildDir, "kotlin-build").apply { mkdirs() } private val buildCacheStorage = BuildCacheStorage(workingDir) + private val shouldReportMemoryUsage = System.getProperty(SHOULD_REPORT_MEMORY_USAGE_PROPERTY) != null internal val artifactDifferenceRegistryProvider: ArtifactDifferenceRegistryProvider get() = buildCacheStorage @@ -75,9 +78,7 @@ internal class KotlinGradleBuildServices private constructor(gradle: Gradle): Bu // There is function with the same name in BuildAdapter, // but it is called before any plugin can attach build listener fun buildStarted() { - if (log.isDebugEnabled) { - startMemory = getUsedMemoryKb()!! - } + startMemory = getUsedMemoryKb() } override fun buildFinished(result: BuildResult) { @@ -111,14 +112,13 @@ internal class KotlinGradleBuildServices private constructor(gradle: Gradle): Bu } } - if (kotlinCompilerCalled) { - startMemory?.let { startMemoryCopy -> - getUsedMemoryKb()?.let { endMemory -> - // the value reported here is not necessarily a leak, since it is calculated before collecting the plugin classes - // but on subsequent runs in the daemon it should be rather small, then the classes are actually reused by the daemon (see above) - log.kotlinDebug("[PERF] Used memory after build: $endMemory kb (difference since build start: ${"%+d".format(endMemory - startMemoryCopy)} kb)") - } - } + if (shouldReportMemoryUsage) { + val startMem = startMemory!! + val endMem = getUsedMemoryKb()!! + + // the value reported here is not necessarily a leak, since it is calculated before collecting the plugin classes + // but on subsequent runs in the daemon it should be rather small, then the classes are actually reused by the daemon (see above) + log.lifecycle("[KOTLIN][PERF] Used memory after build: $endMem kb (difference since build start: ${"%+d".format(endMem - startMem)} kb)") } closeArtifactDifferenceRegistry() @@ -161,7 +161,7 @@ internal class KotlinGradleBuildServices private constructor(gradle: Gradle): Bu } private fun getUsedMemoryKb(): Long? { - if (!log.isDebugEnabled) return null + if (!shouldReportMemoryUsage) return null log.lifecycle(FORCE_SYSTEM_GC_MESSAGE) System.gc()