Skip to content

Commit 793df5a

Browse files
Fix(dcsctp): Fix memory leak. (#2182)
There were reference cycles through JNI, which the garbage collector can't detect.
1 parent af2ff24 commit 793df5a

File tree

2 files changed

+10
-5
lines changed

2 files changed

+10
-5
lines changed

jvb/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113
<dependency>
114114
<groupId>${project.groupId}</groupId>
115115
<artifactId>jitsi-dcsctp</artifactId>
116-
<version>1.0-2-g2d8eee4</version>
116+
<version>1.0-3-gaf9d564</version>
117117
</dependency>
118118
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
119119
<!-- we inherit an old version of slf4j-api from tinder, which pcap4j doesn't work with. Adding slf4j-api 1.7.30 (the current stable) as a dep of jvb fixes the problem. -->

jvb/src/main/kotlin/org/jitsi/videobridge/dcsctp/DcSctpTransport.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import org.jitsi.utils.logging2.Logger
2727
import org.jitsi.utils.logging2.createChildLogger
2828
import org.jitsi.videobridge.sctp.SctpConfig
2929
import org.jitsi.videobridge.util.TaskPools
30+
import java.lang.ref.WeakReference
3031
import java.time.Clock
3132
import java.time.Instant
3233
import java.util.concurrent.Future
@@ -109,7 +110,7 @@ abstract class DcSctpBaseCallbacks(
109110
) : DcSctpSocketCallbacks {
110111
/* Methods we can usefully implement for every JVB socket */
111112
override fun createTimeout(p0: DcSctpSocketCallbacks.DelayPrecision): Timeout {
112-
return ATimeout()
113+
return ATimeout(transport)
113114
}
114115

115116
override fun Now(): Instant {
@@ -142,7 +143,11 @@ abstract class DcSctpBaseCallbacks(
142143
transport.logger.info("Surprising SCTP callback: incoming streams ${incomingStreams.joinToString()} reset")
143144
}
144145

145-
private inner class ATimeout : Timeout {
146+
private class ATimeout(transport: DcSctpTransport) : Timeout {
147+
// This holds a weak reference to the transport, to break JNI reference cycles
148+
private val weakTransport = WeakReference(transport)
149+
private val transport: DcSctpTransport?
150+
get() = weakTransport.get()
146151
private var timeoutId: Long = 0
147152
private var scheduledFuture: ScheduledFuture<*>? = null
148153
private var future: Future<*>? = null
@@ -152,11 +157,11 @@ abstract class DcSctpBaseCallbacks(
152157
scheduledFuture = TaskPools.SCHEDULED_POOL.schedule({
153158
/* Execute it on the IO_POOL, because a timer may trigger sending new SCTP packets. */
154159
future = TaskPools.IO_POOL.submit {
155-
transport.socket.handleTimeout(timeoutId)
160+
transport?.socket?.handleTimeout(timeoutId)
156161
}
157162
}, duration, TimeUnit.MILLISECONDS)
158163
} catch (e: Throwable) {
159-
transport.logger.warn("Exception scheduling DCSCTP timeout", e)
164+
transport?.logger?.warn("Exception scheduling DCSCTP timeout", e)
160165
}
161166
}
162167

0 commit comments

Comments
 (0)