我创建了一个应用程序,它基本上使用机器人在客户端获取和映像,并且每隔几秒就发送到服务器,这样我就可以看到另一台PC上正在发生的事情。问题似乎是它一直将图像保存在数组或其他东西中,因为几秒钟后它就会崩溃。我刚收到图像并在屏幕上写下来。然而,过了一段时间,它给了我一个OutOfMemory。有没有人暗示可能导致它的原因?
以下是所请求的代码段:
服务器:
private class Conexao extends Thread {
public static final int PORTA = 12000;
public ObjectOutputStream out;
public ObjectInputStream in;
public Image image;
private boolean fim;
public Conexao(String ip) throws IOException {
try {
Socket socket = new Socket(ip, Conexao.PORTA);
this.out = new ObjectOutputStream(socket.getOutputStream());
this.in = new ObjectInputStream(socket.getInputStream());
} catch (IOException e) {
throw e;
}
}
public void encerrar() {
this.fim = true;
}
@Override
public void run() {
this.fim = false;
while (!this.fim) {
Mensagem mensagem = null;
try {
mensagem = ((Mensagem) in.readObject());
} catch (IOException | ClassNotFoundException e) {
}
if (mensagem != null) {
this.image = mensagem.getImage();
Cliente.this.painel.repaint();
}
}
}
}
客户端:
private static class Conexao extends Thread {
private static Image CURSOR;
static {
try {
CURSOR = ImageIO.read(new File("images\\mouse.png"));
} catch (IOException e) {
CURSOR = null;
}
}
private ObjectOutputStream out;
private ObjectInputStream in;
public Conexao() throws IOException {
try {
ServerSocket serverSocket = new ServerSocket(Servidor.PORTA, 1);
Socket socket = serverSocket.accept();
this.out = new ObjectOutputStream(socket.getOutputStream());
this.in = new ObjectInputStream(socket.getInputStream());
} catch (IOException e) {
throw e;
}
}
@Override
public void run() {
try {
Robot robot = new Robot();
for (;;)
try {
Thread.sleep(10);
Point p = MouseInfo.getPointerInfo().getLocation();
BufferedImage img = robot.createScreenCapture(new Rectangle(0, 0, Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height));
if (Conexao.CURSOR != null) {
img.getGraphics().drawImage(CURSOR, p.x, p.y, null);
} else {
Graphics2D g = (Graphics2D) img.getGraphics();
g.setColor(Color.WHITE);
g.fillOval(p.x - 5, p.y - 5, 10, 10);
g.setStroke(new BasicStroke(2));
g.setColor(Color.BLACK);
g.drawOval(p.x - 5, p.y - 5, 10, 10);
g.dispose();
}
this.out.writeObject(new Mensagem(img, p));
this.out.flush();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
} catch (AWTException e) {
}
}
}
答案 0 :(得分:3)
答案 1 :(得分:1)
OutOfMemory是由堆空间不足引起的。
您可以尝试一些操作:
确保在运行应用程序时有足够大的堆空间可用。 (-Xmx128M
在java命令行上,其中128被您想要的兆字节数替换掉)
释放所有引用(通过让变量超出范围或通过显式设置对象变量为null)释放到发送图片后不再需要的对象。
如果这无助于尝试重用对象而不是创建新对象。
答案 2 :(得分:1)
尝试在this.out.reset();
后调用this.out.flush();
。
这似乎是ObjectOutputStream的一个问题,它(根据Serialization FAQ和this site)保留了写入其中的所有对象的缓存,以便可以将重复的对象优化为缓存引用。在重新发送对象之前对象中的值发生更改时,这也会导致问题,但缓存的对象会保留旧值。在这两种情况下,调用reset()
都可以解决问题。不幸的是,课程文档中没有解释这一点。
答案 3 :(得分:0)
在没有看到任何代码的情况下,您很可能填充的是byte[]
或ByteArrayOutputStream
,它是类或实例作用域。您应该将收到的内容写入文件,然后根据需要访问它。这意味着每当您切换到新图像时,都会删除对内容的引用(通过使其超出范围)。
如果您可以提供有关应用程序如何运作的更多详细信息,则其他人应该能够查明问题。