2016-03-23 2 views
0

Ich verwende die folgende Methode, um meine Verbindung am Leben zu halten, wenn sie geschlossen wird. Ich bemerkte, dass die RAM-Nutzung um 700 MB zugenommen hatte, als sie eine Woche lang lief und der Socks-Port hundertstel lief. Mache ich etwas falsch?Das Initialisieren eines neuen Sockets in Java erhöht die RAM-Auslastung.

Wenn es eine Woche lang ausgeführt wird, ohne dass so viele neue Sockets initialisiert werden müssen, ist die RAM-Nutzung geringer.

import ws.JettyWebSocketClient; 

public class connectionKeeper extends Thread { 
public void run(){ 

    lib.print(">>> Connection thread running"); 


    do{ 

     lib.writeLog("Opening new websocket connection"); 

     try{ 

      GVL.socketCounter++; 

      GVL.ws = new JettyWebSocketClient(); 

      GVL.ws.run(); 

     }catch(Exception e){ 
      e.printStackTrace(); 
      lib.error("Error: connectionKeeper: " + e.toString()); 
     } 

     // if we are here, we got an error or the socket has executed the run() -method to end   
     lib.sleep(2000); 

    }while(true); 
} 

} 

-

public class JettyWebSocketClient { 

private boolean connected=false; 
private WebSocketClient client=new WebSocketClient(); 

public void run() { 

    MyWebSocket socket = new MyWebSocket(); 

    ClientUpgradeRequest request; 

    URI destinationUri = null; 
    try { 
     destinationUri = new URI("wss://example.com:3000/ws"); 
    } catch (URISyntaxException e1) { 
     e1.printStackTrace(); 
     lib.error("Jetty.runA(): " + e1.toString()); 
    } 

    SslContextFactory sslContextFactory = new SslContextFactory(); 
    Resource keyStoreResource = Resource.newResource(this.getClass().getResource("/cert.jks")); 
    sslContextFactory.setKeyStoreResource(keyStoreResource); 
    sslContextFactory.setKeyStorePassword("pass"); 

    client=new WebSocketClient(sslContextFactory); 

    connected=false; 

    try { 
     client.start(); 
     request = new ClientUpgradeRequest(); 
     System.out.println("SOCKET" + GVL.socketCounter+ ":\tConnecting to " + destinationUri.toString()); 
     client.connect(socket, destinationUri, request); 

     do{ 
      socket.awaitClose(10); 
     }while(connected); 

    } catch (Throwable t) { 
     t.printStackTrace(); 
     lib.error("Jetty.runB(): " + t.toString()); 
    } 

} 


public boolean send(JSONObject message){ 

    String msg=message.toString(); 
    System.out.println("SOCKET" + GVL.socketCounter+ ":\tSending msg:\t" + msg); 

    for(Session s: client.getOpenSessions()) { 
     if (s.isOpen()) { 
      try { 
       s.getRemote().sendString(msg); 
       return true; 
      } catch (IOException e) { 
       e.printStackTrace(); 
       lib.error(e.toString()); 
      } 
     } 
    } 

    return false; 
} 

public String status(){ 
    return this.client.getState(); 
} 

public boolean isConnected() { 
    return connected; 
} 

public void disconnect(){ 

    lib.print("Disconnecting..."); 

    setConnected(false); 

    try { 

     try{ 
      client.stop(); 
     } catch (InterruptedException e) { 
// sometimes it gets here, sometimes not.. hmm 
     } 


    } catch(Exception a){ 
     lib.error("Jetty.disconnect():\t" + a.toString()); 
    } 

    lib.print("Disconnected..."); 
} 

public void setConnected(boolean newval) { 
    connected=newval; 
} 

@WebSocket 
public class MyWebSocket { 


    private final CountDownLatch closeLatch = new CountDownLatch(1); 

    @OnWebSocketConnect 
    public void onConnect(Session session) { 

     System.out.println("SOCKET" + GVL.socketCounter+ ":\tCONNECTED"); 
     setConnected(true); 

    } 

    @OnWebSocketMessage 
    public void onMessage(String message) { 
     messaging.handleMsg(message); // this method uses received data to calculate some things 
    } 

    public void onError(int statusCode, String reason){ 
     lib.error("SOCKET" + GVL.socketCounter+ ":\tError:\t" + reason + "/Code: " + statusCode); 
    } 

    @OnWebSocketClose 
    public void onClose(int statusCode, String reason) { 
     lib.error("SOCKET" + GVL.socketCounter+ ":\tClosed:\t" + reason + "/Code: " + statusCode); 

     setConnected(false); 

    } 

    public void awaitClose(int n) { 
     try { 
      this.closeLatch.await(n, TimeUnit.SECONDS); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      lib.error("SOCKET" + GVL.socketCounter+ ": Jetty.awaitClose():" + e.toString()); 

      disconnect(); // useless? 
     } 
    } 
} 

} 

Antwort

0

Bewahren Sie keine Neuerstellung der WebSocketClient Objekt, erstellen Sie nur 1 dieser und wieder verbinden, wenn Sie wollen.

Denken Sie an die WebSocketClient als Browser.

  • Jede client.start() wie Sie diesen Browser starten.
  • Jeder client.connect() beim Öffnen einer Registerkarte auf eine neue Webseite.

Die teure Operation, den Browser zu starten, tun Sie immer und immer und immer wieder. Die billige Operation, die Verbindung zu einer Website, das Öffnen neuer Tabs, das Schließen anderer, geht nicht. Stattdessen werden Sie "dang, ich muss erneut verbinden, lass mich den Browser stoppen, und starten Sie es erneut verbinden"