我有一個Socket,它通過ObjectOutputStream每隔幾秒向客戶端發送一個對象列表。在服務器端,在每個writeObject(myList)
後執行flush
然後reset
。使用VisualVM檢查內存使用情況,在服務器上沒有內存泄漏,但在客戶端上,似乎先前讀取的列表保留在內存中。我試圖在客戶端的ObjectInputStream上執行reset
,但看起來像ObjectInputStream不支持此方法(它會拋出java.io.IOException: mark/reset not supported
)。ObjectInputStream消耗太多內存
這是我的服務器套接字:
public class ConsultaBombas {
public static void inicializarServidorSocket() {
try {
ServerSocket serverSocket = new ServerSocket(5963);
Thread thread = new Thread(() -> {
while (!serverSocket.isClosed()) {
try {
final Socket socket = serverSocket.accept();
new ThreadComunicacao(socket).start();
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.setName("Consulta bombas (Inicializador)");
thread.start();
} catch (Exception e) {
e.printStackTrace();
}
}
static class ThreadComunicacao extends Thread {
private Socket socket;
public ThreadComunicacao(Socket socket) {
this.socket = socket;
setName("Consulta bombas (Comunicação) com início: " + new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new Date()));
}
@Override
public void run() {
try {
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
while (!socket.isClosed()) {
List<Bomba> bombas = new DaoBomba().findAll();
out.writeObject(bombas);
out.flush();
out.reset();
Thread.sleep(1000);
}
} catch (SocketException e) {
if (e.getLocalizedMessage() != null && e.getLocalizedMessage().equalsIgnoreCase("Connection reset by peer: socket write error")) {
System.out.println("Cliente desconectou...");
} else {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
的,這是(開始start()方法)的客戶端:
public class ConsultaBombasClient {
private Socket socket;
private Thread threadConsulta;
public ConsultaBombasClient(BombasListener bombasListener, String maquinaDestino) {
threadConsulta = new Thread(() -> {
try {
Thread.currentThread().setName("Consulta Bombas");
System.out.println("Endereço bagual: "+maquinaDestino);
socket = new Socket(maquinaDestino, 5963);
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
Object leitura;
while ((leitura = in.readObject()) != null) {
List<Bomba> bombas = (List<Bomba>) leitura;
bombasListener.run(bombas);
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
});
threadConsulta.setDaemon(true);
}
public void start() {
threadConsulta.start();
}
public interface BombasListener {
void run(List<Bomba> bombas);
}
}
我到底做錯了什麼?
BombasListener實現是否可能保留對之前列表的引用? – Berger
我評論了BombasListener實現中的所有內容,只是爲了檢查這一點,但內存問題仍然存在。 –
@MateusViccari,垃圾收集不是直接的,你有沒有真正的記憶麻煩?您是否嘗試過使用低'-Xmx'值運行客戶端,您是否收到'OutOfMemoryError'? – user3707125