这个问题起初可能看起来有点微不足道,但是自从我开始实现这个问题以来,我遇到了奇怪的OutOfMemory问题。查看Java Heap Dumps后,我知道内存泄漏与ObjectOutputStream变量有关。不用多说,这里是代码:
在我的构造函数中,我正在设置将保存输入/输出流变量的字段变量。除此之外,我正在创建另外两组变量,以便我在自定义对象和纯基元上专门执行IO时:
public SingleServer(Socket s, int maxThreads) {
client = s;
serversCreated.incrementAndGet();
try {
is = client.getInputStream();
os = client.getOutputStream();
ois = new ObjectInputStream(is);
oos = new ObjectOutputStream(os);
dis = new DataInputStream(is);
dos = new DataOutputStream(os);
} catch (Exception e) {
// ...
}
print("Client Connected");
}
现在,之前,所有存储的OOS都是对象输出流。那么,你可能会问为什么我要经历创建这些字段的麻烦?答案是我想将基元的发送与发送自定义对象与发送纯字节分开。我认为Java可以像这样分离出来。
我注意到的是突然而且很难预测某些对象现在会导致OutOfMemory错误导致我的程序崩溃。我知道我可以忘记为IO类使用所有这些不同的装饰器,但我想了解为什么会出现这些内存不足错误?
答案 0 :(得分:2)
在两个独立的包装器中包含相同的InputStream
是一个不受支持的习语。第一个包装器可能会立即读取一些输入以填充其缓冲区;第二个可能会尝试做同样的事情。每个包装器都是免费的(甚至鼓励),以便它可以自行决定是否可以完全读出它的基础流。
所以,简而言之,
多次装饰IO流是否存在根本错误?
是的,有。