kotlinx.coroutines icon indicating copy to clipboard operation
kotlinx.coroutines copied to clipboard

Guard against OutOfMemoryError in coroutine internals

Open dkhalanskyjb opened this issue 11 months ago • 0 comments
trafficstars

We got a report of coroutines failing to finish when an OOM happens. The internal link is https://youtrack.jetbrains.com/issue/IJPL-172305, and here is the relevant part of the stacktrace:

kotlinx.coroutines.CoroutinesInternalError: Fatal exception in coroutines machinery for DispatchedContinuation[Dispatchers.EDT, Continuation at com.
        at kotlinx.coroutines.DispatchedTask.handleFatalException$kotlinx_coroutines_core(DispatchedTask.kt:142)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:113)
Caused by: java.lang.OutOfMemoryError: Java heap space
        at java.base/jdk.internal.org.objectweb.asm.SymbolTable.<init>(SymbolTable.java:156)
        at java.base/jdk.internal.org.objectweb.asm.ClassWriter.<init>(ClassWriter.java:297)
        at java.base/jdk.internal.org.objectweb.asm.ClassWriter.<init>(ClassWriter.java:267)
        at java.base/java.lang.invoke.InvokerBytecodeGenerator.classFilePrologue(InvokerBytecodeGenerator.java:270)
        at java.base/java.lang.invoke.InvokerBytecodeGenerator.generateCustomizedCodeBytes(InvokerBytecodeGenerator.java:753)
        at java.base/java.lang.invoke.InvokerBytecodeGenerator.generateCustomizedCode(InvokerBytecodeGenerator.java:712)
        at java.base/java.lang.invoke.LambdaForm.compileToBytecode(LambdaForm.java:849)
        at java.base/java.lang.invoke.LambdaForm.prepare(LambdaForm.java:807)
        at java.base/java.lang.invoke.MethodHandle.<init>(MethodHandle.java:482)
        at java.base/java.lang.invoke.BoundMethodHandle.<init>(BoundMethodHandle.java:52)
        at java.base/java.lang.invoke.BoundMethodHandle$Species_L.<init>(BoundMethodHandle.java:210)
        at java.base/java.lang.invoke.BoundMethodHandle$Species_L.make(BoundMethodHandle.java:225)
        at java.base/java.lang.invoke.BoundMethodHandle.makeReinvoker(BoundMethodHandle.java:114)
        at java.base/java.lang.invoke.DirectMethodHandle.rebind(DirectMethodHandle.java:148)
        at java.base/java.lang.invoke.MethodHandleImpl.makePairwiseConvertByEditor(MethodHandleImpl.java:289)
        at java.base/java.lang.invoke.MethodHandleImpl.makePairwiseConvert(MethodHandleImpl.java:265)
        at java.base/java.lang.invoke.MethodHandleImpl.makePairwiseConvert(MethodHandleImpl.java:382)
        at java.base/java.lang.invoke.MethodHandle.asTypeUncached(MethodHandle.java:905)
        at java.base/java.lang.invoke.MethodHandle.asType(MethodHandle.java:870)
        at java.base/jdk.internal.reflect.MethodHandleIntegerFieldAccessorImpl.fieldAccessor(MethodHandleIntegerFieldAccessorImpl.java:44)
        at java.base/jdk.internal.reflect.MethodHandleAccessorFactory.newFieldAccessor(MethodHandleAccessorFactory.java:156)
        at java.base/jdk.internal.reflect.ReflectionFactory.newFieldAccessor(ReflectionFactory.java:145)
        at java.base/java.lang.reflect.Field.acquireOverrideFieldAccessor(Field.java:1200)
        at java.base/java.lang.reflect.Field.getOverrideFieldAccessor(Field.java:1169)
        at java.base/java.lang.reflect.Field.get(Field.java:444)
        at kotlin.coroutines.jvm.internal.DebugMetadataKt.getLabel(DebugMetadata.kt:96)
        at kotlin.coroutines.jvm.internal.DebugMetadataKt.getStackTraceElement(DebugMetadata.kt:44)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.getStackTraceElement(ContinuationImpl.kt:76)
        at kotlinx.coroutines.debug.internal.DebugProbesImpl.realCaller(DebugProbesImpl.kt:462)
        at kotlinx.coroutines.debug.internal.DebugProbesImpl.updateRunningState(DebugProbesImpl.kt:451)
        at kotlinx.coroutines.debug.internal.DebugProbesImpl.updateState(DebugProbesImpl.kt:428)
        at kotlinx.coroutines.debug.internal.DebugProbesImpl.probeCoroutineResumed$kotlinx_coroutines_core(DebugProbesImpl.kt:419)

The only thing we can do in a scenario when any allocation can fail is to avoid allocating in the parts of the library responsible for liveness.

dkhalanskyjb avatar Nov 26 '24 13:11 dkhalanskyjb