IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Multimédia Java Discussion :

Problème mémoire : Reception de screenshots par socket (VNC like)


Sujet :

Multimédia Java

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 2
    Points : 1
    Points
    1
    Par défaut [Résolu]Problème mémoire : Reception de screenshots par socket (VNC like)
    Bonjour à tous

    Je suis sur un problème épineux, celui de créer une application de prise de contrôle à distance.

    J'ai réussi à créer le serveur qui envoie des Screenshots tout les secondes à un client qui les reçoit et les affiche.
    Le client peut émettre des Actions (clique souris / appuie clavier) sur l'écran à distance qui seront alors interprétées.

    Problème : plus je prends de screen (donc plus le programme est lancé longtemps), plus mon application mange de la mémoire ! Et cela des deux côté (serveur et client). J'ai donc la mémoire qui finie par saturée. Augmenter la taille du Heap ne changerait rien et ne ferait alors que retarder le problème.

    Je ne comprends pas d'où peut venir cette accumulation de données, logiquement j'utilise toujours la même image pour les screenshots.
    J'ai déjà essayé des flush(), des graphics.dispose() (quand j'utilisais un JPanel avec la méthode PaintComponent(Graphics g)) mais rien n'y fait

    Code du thread d'envoie des screens
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    	public void run(){
    		//flux de sortie des screens
    		ObjectOutputStream outObject = null;
    		//robot pour prendre le screen
    		Robot robot = null;
     
    		try {
    			outObject = new ObjectOutputStream(socketClient.getOutputStream());
    			robot = new Robot();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} catch (AWTException e) {
    			e.printStackTrace();
    		}
     
    		while(true){
    			try {
    				//on envoie le screen au client (tableau de bytes)
    				outObject.writeObject(takeScreen(robot));
    				//on vide le flux
    				outObject.flush();
    				//on dort 1 seconde
    				Thread.sleep(1000);
    			} catch (IOException e) {
    				e.printStackTrace();
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    	}
     
    	public Object takeScreen(Robot robot){
    		Toolkit defaultToolkit = Toolkit.getDefaultToolkit();
    	    Rectangle screenRect = new Rectangle(defaultToolkit.getScreenSize());
    		ByteArrayOutputStream bout = new ByteArrayOutputStream();
    		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bout);
    		try {
    			encoder.encode(robot.createScreenCapture(screenRect));
    		} catch (ImageFormatException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		return bout.toByteArray();
    	}
    Code du thread de réception des screens côté client
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    	public void run(){
    		try {
    			//creation du flux d'entree des screenshots
    			ObjectInputStream inObject = new ObjectInputStream(socketServer.getInputStream());
    			while(true){
    				//arrivee d'un tableau de bytes
    				byte[] image = (byte[])inObject.readObject();
    				//passage en image jpg
    			    ByteArrayInputStream bin = new ByteArrayInputStream(image);
    			    JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(bin);
    			    final BufferedImage img = decoder.decodeAsBufferedImage();
    			    //modification du JLabel "iconLabel" (met la nouvelle image)
    			    client.getIconLabel().setIcon(new ImageIcon(img));
    			}
    		} catch (IOException e) {
    			e.printStackTrace();
    		} catch (ClassNotFoundException e) {
    			e.printStackTrace();
    		}
    	}

    voila la partie de mon code qui je pense pose problème

    Je vous remercie énormément par avance si vous voyez une grosse erreur qui serait la cause de cette augmentation de taille du programme en mémoire.

    Pour plus de détails, je répondrais à vos questions.

  2. #2
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Auto réponse :
    J'ai enfin trouvé la cause de cette augmentation en passant beaucoup de temps à fouiner sur google. Je vais poster la solution trouvée qui pourrait aider des gens ayant un jour le même problème.

    côté serveur, envoie des screens :
    ajouter un reset sur le flux de sortie d'objet pour vider le cache Objet
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    [...]
    //on envoie le screen au client (tableau de bytes)
    outObject.writeObject(takeScreen(robot));
    //on vide le flux
    outObject.flush();
    //on reset le flux
    outObject.reset();
    [...]
    côté serveur, création du screen :
    il faut décomposer la prise du screenshot et son encodage en jpeg pour pouvoir faire un flush sur le screenshot
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [...]
    BufferedImage bi = robot.createScreenCapture(screenRect);
    encoder.encode(bi);
    bi.flush();
    [...]
    côté client, réception du screen :
    ImageIcon imIcon est un attribut privé du Thread de reception du screen
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    	public void run(){
    		try {
    			//creation du flux d'entree des screenshots
    			ObjectInputStream inObject = new ObjectInputStream(socketServer.getInputStream());
    			while(connecte){
    				//arrivee d'un tableau de bytes
    				image = (byte[])inObject.readObject();
    				//passage en image jpg
    				bin = new ByteArrayInputStream(image);
    				decoder = JPEGCodec.createJPEGDecoder(bin);
    				img = decoder.decodeAsBufferedImage();
    				//modification de l'ihm (met la nouvelle image)
    				imIcon = new ImageIcon(img);
    				client.getIconLabel().setIcon(imIcon);
    			}
    		} catch (IOException e) {
    			connecte = false;
    			client.dispose();
    		} catch (ClassNotFoundException e) {
    			connecte = false;
    			client.dispose();
    		}
    		JOptionPane.showMessageDialog(null,"Connexion perdue");
    		System.exit(0);
    	}
    Tout fonctionne maintenant à merveille, merci aux gens qui ont lu mon problème sans pour autant pouvoir le solutionner.
    J'espère que j'en aidera quelques uns

Discussions similaires

  1. [Débutant] Problème Envoi/reception de donnee par socket
    Par Kisskool83 dans le forum VB.NET
    Réponses: 2
    Dernier message: 30/06/2011, 14h11
  2. Probleme reception de donnees par Socket
    Par herrs dans le forum Général Dotnet
    Réponses: 2
    Dernier message: 10/07/2008, 12h29
  3. Problème de communication par socket
    Par odjosc dans le forum Réseau/Web
    Réponses: 3
    Dernier message: 20/06/2006, 15h57
  4. Problème de communication par sockets
    Par Linio dans le forum Entrée/Sortie
    Réponses: 33
    Dernier message: 06/05/2006, 19h50
  5. Problème mémoire avec une dll par chargement dynamique
    Par widze19 dans le forum C++Builder
    Réponses: 6
    Dernier message: 15/12/2003, 14h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo