在类中使用装饰的OutputStream / InputStream字段

时间:2013-08-26 17:08:22

标签: java stream garbage-collection out-of-memory decorator

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

1 个答案:

答案 0 :(得分:2)

在两个独立的包装器中包含相同的InputStream是一个不受支持的习语。第一个包装器可能会立即读取一些输入以填充其缓冲区;第二个可能会尝试做同样的事情。每个包装器都是免费的(甚至鼓励),以便它可以自行决定是否可以完全读出它的基础流。

所以,简而言之,

  

多次装饰IO流是否存在根本错误?

是的,有。