简体   繁体   中英

Initializing a new socket in Java increases RAM usage

I use the method below to keep my connection alive if it closes. I noticed that when it had run for a week and there was hundreth socket going on, the RAM usage had increased by 700 MB. Am I doing something wrong?

If it runs for a week without needing to initialize so many new sockets, the RAM usage is smaller.

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?
        }
    }
}

}

Don't keep recreating the WebSocketClient object, just create 1 of those and reconnect when you want to.

Think of the WebSocketClient as the browser.

  • Each client.start() as you starting up that browser.
  • Each client.connect() as you opening a tab to a new web page.

The expensive operation, starting the browser, you are doing over and over and over again. The cheap operation, connecting to a website, opening new tabs, closing others, you are not doing. Instead, you are going "dang, i need to reconnect, let me stop the browser, and restart it to reconnect"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM