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();
}
}
}
- 图像在 Frame 对象中作为字节数组。
只需将图像直接写入套接字输出流即可。摆脱对象流和字节数组流。
我正在研究流媒体网络摄像头。
现在我可以 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();
}
}
}
- 图像在 Frame 对象中作为字节数组。
只需将图像直接写入套接字输出流即可。摆脱对象流和字节数组流。