Skip to content

Instantly share code, notes, and snippets.

@sschilli
Last active September 6, 2019 18:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sschilli/5692c4582a85daec9a3ace186d8b431c to your computer and use it in GitHub Desktop.
Save sschilli/5692c4582a85daec9a3ace186d8b431c to your computer and use it in GitHub Desktop.
package com.memorytest
import platform.Foundation.NSProcessInfo
import kotlin.native.internal.GC
import kotlin.test.Test
// Test case displaying apparent memory leak in macOS. Watch process memory usage in
// Activity Monitor (sort by PID descending to view it at the top when test is run).
// Usage should increase over 25 second period and never go down even after GC collect.
//
// NOTE: This test does not assert anything so it's not a valid test case, it is used
// only to demonstrate that the GC does not seem to be disposing of some NSObjects
// appropriately. I can give the timer class a single instance of NSProcessInfo
// that it reuses for each call to elapsedRealtime, but the problem would still
// exist that the NSObjects are not being deallocated properly whenever they are
// used elsewhere
class MemoryTest {
@Test
fun `test memory leak`() {
println("testing memory leak")
val timer = Timer()
val startTime = timer.elapsedRealtime()
var currentTime = startTime
// Run loop for 25 seconds to build up lots of NSProcessInfo allocations
while (currentTime - startTime < 25_000L) {
currentTime = timer.elapsedRealtime()
}
GC.start()
GC.collect()
println("GC collected")
}
@Test
fun `endless loop`() {
println("looping forever (check memory usage)")
while (true) {}
}
}
class Timer {
fun elapsedRealtime() = (NSProcessInfo().systemUptime * MILLISECONDS_PER_SECOND).toLong()
companion object {
private const val MILLISECONDS_PER_SECOND = 1000
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment