这个问题一开始可能看起来有点琐碎,但自从我开始实现它以来,我遇到了一些奇怪的OutOfMemory问题。在查看了Java堆转储之后,我知道内存泄漏与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的创建是否会导致垃圾收集器无法正常运行
在两个独立的包装器中包装相同的InputStream
是不受支持的习惯用法。第一个包装器可能立即读取一些输入以填充其缓冲区;第二个可能会尝试做同样的事情。每个包装器都可以自由地(甚至被鼓励)假设它可以根据自己的判断完全读取其底层流。
所以,简而言之,
多次装饰IO流是否存在根本问题?
是的,有。