> I have a java program that open some threads (not too many. around
> 15-20 threads). Sometimes I get the following exception:
>
> java.io.IOException: Too many open files
[...]
> My questions are:
> 1. What are those pipes? How does the jvm uses them?
> 2. When does the jvm closes those pipes?
> 3. Is it possible that I have pipes leak?
> 4. How do I solve my problem?
You've been using Runtime.exec() and not cleaning up the files it
opens.
Each time you call Runtime.exec() to create a child process, the JVM
creates three pipes connecting the stdin, stdout and stderr of the
child to the corresponding streams available from the Process object
returned by Runtime.exec().
You need to close those three streams after the child has terminated.
/gordon

Signature
[ do not email me copies of your followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
andreas - 28 Sep 2004 12:19 GMT
> Each time you call Runtime.exec() to create a child process, the JVM
> creates three pipes connecting the stdin, stdout and stderr of the
> child to the corresponding streams available from the Process object
> returned by Runtime.exec().
>
> You need to close those three streams after the child has terminated.
this means, those streams won't be closed in the finalizer?
does Process.destroy() close them? (how/where would i find out myself next
time...)
andreas
Gordon Beaton - 28 Sep 2004 12:47 GMT
> this means, those streams won't be closed in the finalizer? does
> Process.destroy() close them? (how/where would i find out myself
> next time...)
Most likely they *will* be closed eventually, when the correspoding
streams are finalized. You can look at the source code for the
relevant classes just as well as I can, it's packaged with the JDK. In
some cases you might need the complete JDK source package from
http://developer.sun.com/ .
However you should never rely on the garbage collector for collecting
"external" resources like file descriptors, at least not in any timely
manner.
If a class provides a method for the explicit purpose of closing
or releasing it, then you should use it. IMO it's bad style to rely on
the garbage collector to do it for you if methods are available.
For one thing, gc doesn't even know about open file descriptors.
Remember that it's lack of memory, not lack of file descriptors that
triggers gc. Since file descriptors are a much scarcer resource than
memory, you will most likely run out of them long before memory is
low. In fact, you already did.
On the other hand, the Process class itself should probably close the
streams as soon as the reaper thread cleans up after the terminated
child process. In particular you shouldn't be forced to close them if
you never used them in the first place, as is often the case.
/gordon

Signature
[ do not email me copies of your followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
Boaz - 28 Sep 2004 17:03 GMT
> You've been using Runtime.exec() and not cleaning up the files it
> opens.
[quoted text clipped - 7 lines]
>
> /gordon
Thanks for the quick response.
How do I "close those three streams":
1. Can I use Process.destroy()? does it has effect after the child
terminated?
2. If I wait for the thread that called the Runtime.exec() to finish
(and also other threads that have a refernece to the Process), will it
close the streams?
3. If I use getInputStream(), for example, and then call the close()
method, does that do the job (I will do that of course for all the 3)?
Thanks again,
Boaz.
Gordon Beaton - 29 Sep 2004 07:17 GMT
> How do I "close those three streams":
> 1. Can I use Process.destroy()? does it has effect after the child
> terminated?
No.
> 2. If I wait for the thread that called the Runtime.exec() to finish
> (and also other threads that have a refernece to the Process), will it
> close the streams?
No.
> 3. If I use getInputStream(), for example, and then call the close()
> method, does that do the job (I will do that of course for all the 3)?
Yes, "get" each of the streams (input, output, error) and call its
close() method.
/gordon

Signature
[ do not email me copies of your followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e