0

这个问题起初可能看起来有点微不足道,但自从我开始实施这个问题以来,我遇到了奇怪的 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 是否会导致垃圾收集器无法正常运行?
4

1 回答 1

2

在两个独立的包装器中包装相同InputStream的是不受支持的习惯用法。第一个包装器可能会立即读取一些输入来填充其缓冲区;第二个可能会尝试做同样的事情。每个包装器都可以自由(甚至鼓励)假设它可以自行决定完全读取其底层流。

所以,简而言之,

多次装饰 IO 流是否存在根本性问题?

就在这里。

于 2013-08-26T17:22:05.673 回答