webrtc-java icon indicating copy to clipboard operation
webrtc-java copied to clipboard

Leak of observer instances

Open kalaider opened this issue 7 months ago • 0 comments

Describe the bug webrtc-java 0.8.0. Callback instances (all XxxObservers passed to PeerConnectionFactory.createPeerConnection and such) are constantly leaking. In my case I need to create a large number of PCs in a long-running monitoring application which started to eat memory after migration from ice4j to webrtc-java. Heap dump analysis revealed that observers are kept alive by native code (GC Root: Global JNI).

To Reproduce Minimal reproducer:

package org.kalaider.webrtc;

import dev.onvoid.webrtc.PeerConnectionFactory;
import dev.onvoid.webrtc.PeerConnectionObserver;
import dev.onvoid.webrtc.RTCConfiguration;
import dev.onvoid.webrtc.RTCIceCandidate;
import dev.onvoid.webrtc.media.audio.AudioDeviceModule;
import dev.onvoid.webrtc.media.audio.AudioLayer;

import java.time.Duration;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class LeakTestJava {
	private static void createLeak() {
		var pcf = new PeerConnectionFactory(new AudioDeviceModule(AudioLayer.kDummyAudio));
		IntStream.range(0, 1000).forEach(i -> {
			pcf.createPeerConnection(new RTCConfiguration(), new PeerConnectionObserver() {
				private final String bigObject = IntStream.range(0, 1000).mapToObj(j -> "long-string").collect(Collectors.joining(" "));
				@Override public void onIceCandidate(RTCIceCandidate candidate) {
					System.out.println(bigObject);
				}
			}).close();
		});
		pcf.dispose();
		System.out.println("leak created");
	}

	public static void main(String[] args) throws InterruptedException {
		createLeak();
		Thread.sleep(Duration.ofMinutes(10));
	}
}

After leak created message is printed, LeakTestJava$1 is in the top-1 by retained memory size.

Expected behavior Observers should not leak.

Desktop (please complete the following information):

  • OS: Ubuntu
  • Version 23.10

Additional context One suspicious place where the leak is possible is JNI code that passes a pointer to rtc::RefCountedObjects to native webrtc APIs without releasing initial reference.

kalaider avatar Jul 21 '24 16:07 kalaider