这个问题起初可能看起来有点微不足道,但自从我开始实施这个问题以来,我遇到了奇怪的 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 类使用所有这些不同的装饰器,但我想了解为什么会发生这些内存不足错误?
- 多次装饰 IO 流是否存在根本性问题?
- 在实际使用流之前按需装饰流,然后在不再需要时让垃圾收集器处理它会更好吗?
- 作为上述问题的扩展,在一切正常工作且没有内存错误之前,我实际存储的唯一对象是 OOS。然而,现在,内存错误与OOS有关。创建 DOS 或 OS 是否会导致垃圾收集器无法正常运行?