--- old/src/share/classes/java/io/RandomAccessFile.java Tue Jul 10 17:37:26 2012 +++ new/src/share/classes/java/io/RandomAccessFile.java Tue Jul 10 17:37:25 2012 @@ -229,7 +229,7 @@ throw new NullPointerException(); } fd = new FileDescriptor(); - fd.attach(this); + fd.incrementAndGetUseCount(); open(name, imode); } @@ -242,9 +242,7 @@ * @see java.io.FileDescriptor */ public final FileDescriptor getFD() throws IOException { - if (fd != null) { - return fd; - } + if (fd != null) return fd; throw new IOException(); } @@ -270,6 +268,17 @@ synchronized (this) { if (channel == null) { channel = FileChannelImpl.open(fd, true, rw, this); + + /* + * FileDescriptor could be shared by FileInputStream or + * FileOutputStream. + * Ensure that FD is GC'ed only when all the streams/channels + * are done using it. + * Increment fd's use count. Invoking the channel's close() + * method will result in decrementing the use count set for + * the channel. + */ + fd.incrementAndGetUseCount(); } return channel; } @@ -568,13 +577,21 @@ closed = true; } if (channel != null) { + /* + * Decrement FD use count associated with the channel. The FD use + * count is incremented whenever a new channel is obtained from + * this stream. + */ + fd.decrementAndGetUseCount(); channel.close(); } - fd.closeAll(new Closeable() { - public void close() throws IOException { - close0(); - } - }); + + /* + * Decrement FD use count associated with this stream. + * The count got incremented by FileDescriptor during its construction. + */ + fd.decrementAndGetUseCount(); + close0(); } //