ByteArrayInputStream 堆内存不足

ByteArrayInputStream Out of Heap Memory

我正在研究流媒体网络摄像头。
现在我可以 1:1 TCP 网络摄像头通信了。
问题是即使 gc 运行,堆内存也不会下降。
我尝试了 reset()、flush()、close()。
一切看起来都很好,但 new ByteArrayInputStream(f.bytes) 不是。
我觉得图像的字节越来越多,但我不知道如何清除它。

heap memory monitor

这是我的代码。

VideoServerThread.java

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

import common.Frame;

public class VideoServerThread extends Thread
{
    private ServerSocket serverSocket;
    int                  videoServerPort;
    private Socket       socket;
    private JPanel       panel;
    private boolean      calling;

    public VideoServerThread(ServerSocket serverSocket, int videoServerPort, JPanel panel, boolean calling)
    {
        this.serverSocket = serverSocket;
        this.videoServerPort = videoServerPort;
        this.panel = panel;
        this.calling = calling;
    }

    @Override
    public void run()
    {
        System.out.println("Video Server opened!");
        try
        {
            serverSocket = new ServerSocket(videoServerPort);
            socket = serverSocket.accept();
            InputStream in = socket.getInputStream();
            ObjectInputStream ois = new ObjectInputStream(in);
            BufferedImage bufferedImage;
            ByteArrayInputStream inputImage;
            Frame f;
            while (calling)
            {
                f = (Frame) ois.readObject();
                inputImage = new ByteArrayInputStream(f.bytes);
                bufferedImage = ImageIO.read(inputImage);
                panel.getGraphics().drawImage(bufferedImage, 0, 0, panel.getWidth(), panel.getHeight(), null);
                bufferedImage.flush();
                inputImage.close();
            }
        }

        catch (IOException e)
        {
            e.printStackTrace();
        }
        catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        }
    }
}

VideoClientThread.java

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;

import javax.imageio.ImageIO;

import common.Frame;
import video.VideoCap;

public class VideoClientThread extends Thread
{
    private final String formatType = "jpg";
    private VideoCap     videoCap;
    private Socket       socket;
    private String       ip;
    private int          port;
    private boolean      calling;

    public VideoClientThread(VideoCap videoCap, Socket socket, String ip, int port, boolean calling)
    {
        this.videoCap = videoCap;
        this.socket = socket;
        this.ip = ip;
        this.port = port;
        this.calling = calling;
    }

    public void run()
    {
        try
        {
            socket = new Socket(ip, port);
            socket.setSoTimeout(5000);
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            Frame f;
            BufferedImage bufferedImage;
            ByteArrayOutputStream fbaos;
            fbaos = new ByteArrayOutputStream();
            while (calling)
            {
                bufferedImage = videoCap.getOneFrame();
                ImageIO.write(bufferedImage, formatType, fbaos);
                f = new Frame(fbaos.toByteArray());
                oos.writeObject(f);
                bufferedImage.flush();
                fbaos.reset();
                oos.reset();
            }
            fbaos.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

只需将图像直接写入套接字输出流即可。摆脱对象流和字节数组流。