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



这个问题一开始可能看起来有点琐碎,但自从我开始实现它以来,我遇到了一些奇怪的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流是否存在根本问题?

是的,有。

相关内容

  • 没有找到相关文章

最新更新