[英]ObjectInputStream consumes too much memory
我有一个套接字,它每隔几秒钟通过ObjectOutputStream向客户端发送一个对象列表。 在服务器端,每执行一次writeObject(myList)
我都要执行flush
并reset
。 使用VisualVM检查内存使用情况,在服务器上没有内存泄漏,但是在客户端上,以前读取的列表似乎保留在内存中。 我试图在客户端的ObjectInputStream上执行reset
,但看起来ObjectInputStream不支持此方法(它抛出java.io.IOException: mark/reset not supported
)。
这是我的服务器套接字:
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);
}
}
我究竟做错了什么?
垃圾回收不是立即进行的,您有任何实际的内存麻烦吗? 您是否尝试过以低-Xmx
值运行客户端,是否收到OutOfMemoryError
? – user3707125
没错,一段时间后,当内存接近最大堆大小时,它将清除内存中的对象。 我没看到这是因为我的电脑中有很多RAM,但是有了Xmx50m,我可以看到此功能如您所说。 – Mateus Viccari
显然bombasListener.run()
, bombasListener.run()
不会释放提供的列表。
NB ObjectInputStream.readObject()
在流的末尾不返回null。 因此,将此测试用作读取循环的终止条件是不正确的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.