Утечка памяти MediaPlayer'a и Media JavaFX'a

160
03 декабря 2017, 12:49

Добрый день, написал несложный код

@Override
    public void run() {
        for (Map.Entry<String, String> entry : tracks.entrySet()) {
            if (isInterrupted())
                return;
            mediaPlayer = new MediaPlayer(new Media(entry.getValue()));
            mediaPlayer.setOnReady(() -> {
                synchronized (Player.this) {
                    Player.this.notify();
                }
            });
            synchronized (this) {
                try {
                    this.wait();
                } catch (InterruptedException ignored) {
                    return;
                }
            }
            mediaPlayer.currentTimeProperty().addListener(durationChangeListener);
            mediaPlayer.play();
            mediaPlayer.setOnEndOfMedia(() -> {
                synchronized (Player.this) {
                    Player.this.notify();
                }
            });
            synchronized (this) {
                try {
                    this.wait();
                } catch (InterruptedException ignored) {
                    mediaPlayer.stop();
                    return;
                }
            }
        }
    }
    public void complete() {
        mediaPlayer.stop();
        interrupt();
    }

Собственно по нажатию на кнопку создаётся и запускается поток, в нём эти 2 метода. Если нажимаю на другую или эту же кнопку, то сначала вызывается метод complete у старого потока, а только потом создаётся новый. Дело вот в чём, не понимаю как и почему, но память от запуска каждого из этих потоков не освобождается, точнее сами потоки благополучно завершают своё выполнение, но вот я полагаю что во всём виноваты Media, которые создаются в цикле метода run и засовываются в MediaPlayer. У меня 95% памяти занимает массив []int, ЭТО ЧТО ТАКОЕ!? Как это исправить? Гуглил-гуглил и нагуглил про утечку памяти в этих MediaPlayer'e и Media, а как это фиксить не нашёл ;-( PSL помогите, может вы сталкивались с этим ранее...

Вот работающий кусок проблемного кода

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;
import java.util.HashMap;
import java.util.Map;
public class StackExample extends Application {
private Player player;
public static void main(String[] args) {
    launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
    BorderPane borderPane = new BorderPane();
    borderPane.setPrefSize(500, 500);
    Scene scene = new Scene(borderPane);
    primaryStage.setScene(scene);
    Button button = new Button("PLAY");
    button.setOnAction(event -> {
        if (player != null)
            player.complete();
        player = new Player();
        player.start();
    });
    button.setPrefSize(200, 200);
    borderPane.setCenter(button);
    primaryStage.show();
}
public class Player extends Thread {
    private HashMap<String, String> tracks = new HashMap<>();
    private MediaPlayer mediaPlayer;
    public Player() {
        tracks.put("Imagine Dragons - Warrios", "http://cdndl.zaycev.net/play/6480852/mVGBUAsHNeOHQUrtq5OSAe0tZcOETgStESnsyl6b-l9WLeZBKcYT09HEEYmuuO19JwqdNN32vky-gWenJ9EO0TLda5vtQ4w_jC6YvTZZYexZGzirMELPKkKPkneaulavPpfpXc9tdQAyD5DDc-Gtq7Exdo0Fc7ao0vbXURn2NlYWEo5K51R32HmBkKyAhkDpDCkuRQ?dlKind=play&format=json");
        tracks.put("Imagine Dragons – Demons", "http://cdndl.zaycev.net/play/1724020/5ZTIqiGbBGeFz19IJoBK6voM4OjujxTMRkzfvqzyRo2k2cAJn-_61IHhx4ceGipekDpjT_rll1KhR28bug82D7mjS42ibdZ8vAx2VigiH1yN9Dj92ab9f-AtMUK-WKATBscr1mn6bFV_HuSIzg0BN5T20oo?dlKind=play&format=json");
    }
    @Override
    public void run() {
        for (Map.Entry<String, String> entry : tracks.entrySet()) {
            if (isInterrupted())
                return;
            mediaPlayer = new MediaPlayer(new Media(entry.getValue()));
            mediaPlayer.setOnReady(() -> {
                synchronized (StackExample.Player.this) {
                    StackExample.Player.this.notify();
                }
            });
            synchronized (this) {
                try {
                    this.wait();
                } catch (InterruptedException ignored) {
                    mediaPlayer.dispose();
                    return;
                }
            }
            mediaPlayer.play();
            mediaPlayer.setOnEndOfMedia(() -> {
                synchronized (StackExample.Player.this) {
                    StackExample.Player.this.notify();
                }
            });
            synchronized (this) {
                try {
                    this.wait();
                } catch (InterruptedException ignored) {
                    mediaPlayer.stop();
                    mediaPlayer.dispose();
                    return;
                }
            }
        }
    }
    public void complete() {
        mediaPlayer.stop();
        mediaPlayer.dispose();
        interrupt();
        StackExample.this.player = null;
    }
}

}

READ ALSO